1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-22 23:30:07 +02:00

Redefine ODLocker as movable, and it may try-lock only.

This commit is contained in:
Paul Licameli 2016-04-17 09:54:14 -04:00
parent 185d5e132d
commit 94cf94718e
4 changed files with 36 additions and 18 deletions

View File

@ -118,13 +118,11 @@ OSType sf_header_mactype(int format);
// This function wrapper uses a mutex to serialize calls to the SndFile library. // This function wrapper uses a mutex to serialize calls to the SndFile library.
#include "MemoryX.h" #include "MemoryX.h"
#include "ondemand/ODTaskThread.h" #include "ondemand/ODTaskThread.h"
class ODLock;
class ODLocker;
extern ODLock libSndFileMutex; extern ODLock libSndFileMutex;
template<typename R, typename F, typename... Args> template<typename R, typename F, typename... Args>
inline R SFCall(F fun, Args&&... args) inline R SFCall(F fun, Args&&... args)
{ {
ODLocker locker{ libSndFileMutex }; ODLocker locker{ &libSndFileMutex };
return fun(std::forward<Args>(args)...); return fun(std::forward<Args>(args)...);
} }

View File

@ -135,7 +135,7 @@ public:
invalEnd = len; invalEnd = len;
ODLocker locker(mRegionsMutex); ODLocker locker(&mRegionsMutex);
//look thru the region array for a place to insert. We could make this more spiffy than a linear search //look thru the region array for a place to insert. We could make this more spiffy than a linear search
//but right now it is not needed since there will usually only be one region (which grows) for OD loading. //but right now it is not needed since there will usually only be one region (which grows) for OD loading.
@ -420,7 +420,7 @@ bool WaveClip::AfterClip(double t) const
///Delete the wave cache - force redraw. Thread-safe ///Delete the wave cache - force redraw. Thread-safe
void WaveClip::DeleteWaveCache() void WaveClip::DeleteWaveCache()
{ {
ODLocker locker(mWaveCacheMutex); ODLocker locker(&mWaveCacheMutex);
if(mWaveCache!=NULL) if(mWaveCache!=NULL)
delete mWaveCache; delete mWaveCache;
mWaveCache = new WaveCache(); mWaveCache = new WaveCache();
@ -429,7 +429,7 @@ void WaveClip::DeleteWaveCache()
///Adds an invalid region to the wavecache so it redraws that portion only. ///Adds an invalid region to the wavecache so it redraws that portion only.
void WaveClip::AddInvalidRegion(long startSample, long endSample) void WaveClip::AddInvalidRegion(long startSample, long endSample)
{ {
ODLocker locker(mWaveCacheMutex); ODLocker locker(&mWaveCacheMutex);
if(mWaveCache!=NULL) if(mWaveCache!=NULL)
mWaveCache->AddInvalidRegion(startSample,endSample); mWaveCache->AddInvalidRegion(startSample,endSample);
} }
@ -525,7 +525,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
} }
else { else {
// Lock the list of invalid regions // Lock the list of invalid regions
ODLocker locker(mWaveCacheMutex); ODLocker locker(&mWaveCacheMutex);
const double tstep = 1.0 / pixelsPerSecond; const double tstep = 1.0 / pixelsPerSecond;
const double samplesPerPixel = mRate * tstep; const double samplesPerPixel = mRate * tstep;

View File

@ -277,7 +277,7 @@ void ODManager::Start()
// JKC: If there are no tasks ready to run, or we're paused then // JKC: If there are no tasks ready to run, or we're paused then
// we wait for there to be tasks in the queue. // we wait for there to be tasks in the queue.
{ {
ODLocker locker{ mQueueNotEmptyCondLock }; ODLocker locker{ &mQueueNotEmptyCondLock };
if( (!tasksInArray) || paused) if( (!tasksInArray) || paused)
mQueueNotEmptyCond->Wait(); mQueueNotEmptyCond->Wait();
} }

View File

@ -24,6 +24,7 @@
#include <wx/thread.h> #include <wx/thread.h>
#include "../Audacity.h" // contains the set-up of AUDACITY_DLL_API #include "../Audacity.h" // contains the set-up of AUDACITY_DLL_API
#include "../MemoryX.h"
class ODTask; class ODTask;
@ -170,25 +171,44 @@ protected:
#endif // __WXMAC__ #endif // __WXMAC__
// Like wxMutexLocker // class ODLocker
// So you can use the RAII idiom with ODLock, on whatever platform // So you can use the RAII idiom with ODLock, on whatever platform
class ODLocker // Construct with pointer to the lock, or default-construct and later
{ // reset()
// If constructed with only a try-lock, and the lock was not acquired,
// then it returns false when cast to bool
struct ODUnlocker { void operator () (ODLock *p) const { if(p) p->Unlock(); } };
using ODLockerBase = std::unique_ptr<ODLock, ODUnlocker>;
class ODLocker : public ODLockerBase {
public: public:
ODLocker(ODLock &lock) // Lock any bare pointer to ODLock at construction time or when resetting.
: mLock(lock) explicit ODLocker(ODLock *p = nullptr, bool tryOnly = false)
{ {
mLock.Lock(); reset(p, tryOnly);
} }
~ODLocker() void reset(ODLock *p = nullptr, bool tryOnly = false)
{ {
mLock.Unlock(); ODLockerBase::reset(p);
if(p) {
if (tryOnly) {
if (p->TryLock() != 0)
ODLockerBase::reset(nullptr);
}
else
p->Lock();
}
} }
private: // Assume already locked when moving ODLocker. Don't lock again.
ODLocker(ODLocker&& that) : ODLockerBase { std::move(that) } {}
ODLocker &operator= (ODLocker && that) {
ODLockerBase::operator= ( std::move(that) );
return *this;
}
ODLock &mLock; ODLocker(const ODLocker &that) PROHIBITED;
ODLocker &operator= (const ODLocker &that) PROHIBITED;
}; };
#endif //__AUDACITY_ODTASKTHREAD__ #endif //__AUDACITY_ODTASKTHREAD__