1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-22 07:10:06 +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.
#include "MemoryX.h"
#include "ondemand/ODTaskThread.h"
class ODLock;
class ODLocker;
extern ODLock libSndFileMutex;
template<typename R, typename F, typename... Args>
inline R SFCall(F fun, Args&&... args)
{
ODLocker locker{ libSndFileMutex };
ODLocker locker{ &libSndFileMutex };
return fun(std::forward<Args>(args)...);
}

View File

@ -135,7 +135,7 @@ public:
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
//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
void WaveClip::DeleteWaveCache()
{
ODLocker locker(mWaveCacheMutex);
ODLocker locker(&mWaveCacheMutex);
if(mWaveCache!=NULL)
delete mWaveCache;
mWaveCache = new WaveCache();
@ -429,7 +429,7 @@ void WaveClip::DeleteWaveCache()
///Adds an invalid region to the wavecache so it redraws that portion only.
void WaveClip::AddInvalidRegion(long startSample, long endSample)
{
ODLocker locker(mWaveCacheMutex);
ODLocker locker(&mWaveCacheMutex);
if(mWaveCache!=NULL)
mWaveCache->AddInvalidRegion(startSample,endSample);
}
@ -525,7 +525,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
}
else {
// Lock the list of invalid regions
ODLocker locker(mWaveCacheMutex);
ODLocker locker(&mWaveCacheMutex);
const double tstep = 1.0 / pixelsPerSecond;
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
// we wait for there to be tasks in the queue.
{
ODLocker locker{ mQueueNotEmptyCondLock };
ODLocker locker{ &mQueueNotEmptyCondLock };
if( (!tasksInArray) || paused)
mQueueNotEmptyCond->Wait();
}

View File

@ -24,6 +24,7 @@
#include <wx/thread.h>
#include "../Audacity.h" // contains the set-up of AUDACITY_DLL_API
#include "../MemoryX.h"
class ODTask;
@ -170,25 +171,44 @@ protected:
#endif // __WXMAC__
// Like wxMutexLocker
// class ODLocker
// 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:
ODLocker(ODLock &lock)
: mLock(lock)
// Lock any bare pointer to ODLock at construction time or when resetting.
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__