/* * nextpnr -- Next Generation Place and Route * * Copyright (C) 2021 Symbiflow Authors. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef SCOPE_LOCK_H #define SCOPE_LOCK_H #include namespace nextpnr { // Provides a simple RAII locking object. ScopeLock takes a lock when // constructed, and releases the lock on destruction or if "unlock_early" is // called. // // LockingObject must have a method "void lock(void)" and "void unlock(void)". template class ScopeLock { public: ScopeLock(LockingObject *obj) : obj_(obj), locked_(false) { obj_->lock(); locked_ = true; } ScopeLock(const ScopeLock &other) = delete; ScopeLock(const ScopeLock &&other) = delete; ~ScopeLock() { if (locked_) { obj_->unlock(); } } void unlock_early() { if (!locked_) { throw std::runtime_error("Lock already released?"); } locked_ = false; obj_->unlock(); } private: LockingObject *obj_; bool locked_; }; }; // namespace nextpnr #endif /* SCOPE_LOCK_H */