diff -rupN a/doomsday/libdeng2/include/de/data/lockable.h b/doomsday/libdeng2/include/de/data/lockable.h --- a/doomsday/libdeng2/include/de/data/lockable.h 2012-12-28 01:04:26.509229424 -0600 +++ b/doomsday/libdeng2/include/de/data/lockable.h 2012-12-31 23:20:56.350330827 -0600 @@ -56,9 +56,8 @@ public: private: /// Pointer to the internal mutex data. - mutable QMutex _mutex; - - mutable int _lockCount; + struct Instance; + Instance *d; }; } // namespace de diff -rupN a/doomsday/libdeng2/src/data/lockable.cpp b/doomsday/libdeng2/src/data/lockable.cpp --- a/doomsday/libdeng2/src/data/lockable.cpp 2012-12-28 01:04:26.500229536 -0600 +++ b/doomsday/libdeng2/src/data/lockable.cpp 2012-12-31 23:24:37.037571856 -0600 @@ -20,50 +20,69 @@ #include "de/Lockable" #include "de/error.h" -using namespace de; +namespace de { -#define LOCK_TIMEOUT_MS 60000 +struct Lockable::Instance +{ + mutable QMutex mutex; + + mutable int lockCount; + mutable QMutex countMutex; -Lockable::Lockable() : _mutex(QMutex::Recursive), _lockCount(0) + Instance() : mutex(QMutex::Recursive), lockCount(0) + {} +}; + +Lockable::Lockable() : d(new Instance) {} - + Lockable::~Lockable() -{ - while(_lockCount > 0) +{ + d->countMutex.lock(); + while(d->lockCount > 0) { - unlock(); + d->mutex.unlock(); + d->lockCount--; } + d->countMutex.unlock(); + + delete d; } void Lockable::lock() const { - // Acquire the lock. Blocks until the operation succeeds. - if(!_mutex.tryLock(LOCK_TIMEOUT_MS)) - { - /// @throw Error Acquiring the mutex failed due to an error. - throw Error("Lockable::lock", "Failed to lock"); - } + d->countMutex.lock(); + d->lockCount++; + d->countMutex.unlock(); - _lockCount++; + d->mutex.lock(); } void Lockable::unlock() const { - if(_lockCount > 0) - { - _lockCount--; + // Release the lock. + d->mutex.unlock(); - // Release the lock. - _mutex.unlock(); - } + d->countMutex.lock(); + d->lockCount--; + d->countMutex.unlock(); + + DENG2_ASSERT(d->lockCount >= 0); } bool Lockable::isLocked() const { - return _lockCount > 0; + bool result; + d->countMutex.lock(); + result = (d->lockCount > 0); + d->countMutex.unlock(); + return result; } void Lockable::assertLocked() const { DENG2_ASSERT(isLocked()); } + +} // namespace de +