diff --git a/src/app/context_flags.cpp b/src/app/context_flags.cpp index ea81294e5..cb6d81ea2 100644 --- a/src/app/context_flags.cpp +++ b/src/app/context_flags.cpp @@ -37,7 +37,7 @@ void ContextFlags::update(Context* context) if (document) { m_flags |= HasActiveDocument; - if (document->lock(Doc::ReadLock, 0)) { + if (document->readLock(0)) { m_flags |= ActiveDocumentIsReadable; if (document->isMaskVisible()) diff --git a/src/app/doc.cpp b/src/app/doc.cpp index 6d4958b19..db4882f3f 100644 --- a/src/app/doc.cpp +++ b/src/app/doc.cpp @@ -95,6 +95,46 @@ void Doc::setContext(Context* ctx) onContextChanged(); } +bool Doc::canWriteLockFromRead() const +{ + return m_rwLock.canWriteLockFromRead(); +} + +bool Doc::readLock(int timeout) +{ + return m_rwLock.lock(base::RWLock::ReadLock, timeout); +} + +bool Doc::writeLock(int timeout) +{ + return m_rwLock.lock(base::RWLock::WriteLock, timeout); +} + +bool Doc::upgradeToWrite(int timeout) +{ + return m_rwLock.upgradeToWrite(timeout); +} + +void Doc::downgradeToRead() +{ + m_rwLock.downgradeToRead(); +} + +void Doc::unlock() +{ + m_rwLock.unlock(); +} + +bool Doc::weakLock(base::RWLock::WeakLock* weak_lock_flag) +{ + return m_rwLock.weakLock(weak_lock_flag); +} + +void Doc::weakUnlock() +{ + m_rwLock.weakUnlock(); +} + void Doc::setTransaction(Transaction* transaction) { if (transaction) { diff --git a/src/app/doc.h b/src/app/doc.h index eb5590ab0..e2cea2bfc 100644 --- a/src/app/doc.h +++ b/src/app/doc.h @@ -57,7 +57,6 @@ namespace app { // An application document. It is the class used to contain one file // opened and being edited by the user (a sprite). class Doc : public doc::Document, - public base::RWLock, public obs::observable { enum Flags { kAssociatedToFile = 1, // This sprite is associated to a file in the file-system @@ -72,6 +71,17 @@ namespace app { Context* context() const { return m_ctx; } void setContext(Context* ctx); + // Lock/unlock API (RWLock wrapper) + bool canWriteLockFromRead() const; + bool readLock(int timeout); + bool writeLock(int timeout); + bool upgradeToWrite(int timeout); + void downgradeToRead(); + void unlock(); + + bool weakLock(base::RWLock::WeakLock* weak_lock_flag); + void weakUnlock(); + // Sets active/running transaction. void setTransaction(Transaction* transaction); Transaction* transaction() { return m_transaction; } @@ -214,9 +224,15 @@ namespace app { void removeFromContext(); void updateOSColorSpace(bool appWideSignal); + // The document is in the collection of documents of this context. Context* m_ctx; + + // Internal states of the document. int m_flags; + // Read-Write locks. + base::RWLock m_rwLock; + // Undo and redo information about the document. std::unique_ptr m_undo; diff --git a/src/app/doc_access.h b/src/app/doc_access.h index 42cf7cc3c..730e09ef1 100644 --- a/src/app/doc_access.h +++ b/src/app/doc_access.h @@ -82,13 +82,13 @@ namespace app { explicit DocReader(Doc* doc, int timeout) : DocAccess(doc) { - if (m_doc && !m_doc->lock(Doc::ReadLock, timeout)) + if (m_doc && !m_doc->readLock(timeout)) throw CannotReadDocException(); } explicit DocReader(const DocReader& copy, int timeout) : DocAccess(copy) { - if (m_doc && !m_doc->lock(Doc::ReadLock, timeout)) + if (m_doc && !m_doc->readLock(timeout)) throw CannotReadDocException(); } @@ -126,7 +126,7 @@ namespace app { , m_from_reader(false) , m_locked(false) { if (m_doc) { - if (!m_doc->lock(Doc::WriteLock, timeout)) + if (!m_doc->writeLock(timeout)) throw CannotWriteDocException(); m_locked = true;