1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-25 07:43:54 +02:00

Exception safety in: locking of BlockFile for read

This commit is contained in:
Paul Licameli
2016-11-28 14:28:44 -05:00
parent f5fe9281e4
commit ed6f2ea80f
5 changed files with 66 additions and 61 deletions

View File

@@ -163,11 +163,43 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
// not balanced by unlocking calls.
virtual void CloseLock(){Lock();}
protected:
/// Prevents a read on other threads. The basic blockfile runs on only one thread, so does nothing.
virtual void LockRead() const {}
/// Allows reading on other threads.
virtual void UnlockRead() const {}
struct ReadLocker { void operator () ( const BlockFile *p ) const {
if (p) p->LockRead(); } };
struct ReadUnlocker { void operator () ( const BlockFile *p ) const {
if (p) p->UnlockRead(); } };
using ReadLockBase =
movable_ptr_with_deleter< const BlockFile, ReadUnlocker >;
public:
class ReadLock : public ReadLockBase
{
friend BlockFile;
ReadLock ( const BlockFile *p, const BlockFile::ReadUnlocker &u )
: ReadLockBase { p, u } {}
public:
#ifdef __AUDACITY_OLD_STD__
ReadLock (const ReadLock &that) : ReadLockBase( that ) {}
ReadLock &operator= (const ReadLock &that)
{
*((ReadLockBase*)this) = that;
}
#endif
ReadLock(ReadLock&&that) : ReadLockBase{ std::move(that) } {}
using Suspension = std::unique_ptr< const BlockFile, ReadLocker >;
Suspension Suspend() const
{ if (get()) get()->UnlockRead();
return Suspension{ get(), ReadLocker{} }; }
};
// RAII wrapper about the read locking functions
ReadLock LockForRead() const { LockRead(); return { this, ReadUnlocker{} }; }
private:
protected: