VirtualBox

Ignore:
Timestamp:
Dec 10, 2009 12:14:12 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
55834
Message:

Main: preparation for deadlock detection: flatten LockHandle hierarchy, some documentation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/AutoLock.h

    r25286 r25287  
    4848
    4949/**
    50  * Abstract lock operations. See LockHandle and AutoWriteLock for details.
    51  */
    52 class LockOps
    53 {
    54 public:
    55 
    56     virtual ~LockOps() {}
    57 
    58     virtual void lock() = 0;
    59     virtual void unlock() = 0;
    60 };
    61 
    62 /**
    63  * Read lock operations. See LockHandle and AutoWriteLock for details.
    64  */
    65 class ReadLockOps : public LockOps
    66 {
    67 public:
    68 
    69     /**
    70      * Requests a read (shared) lock.
    71      */
    72     virtual void lockRead() = 0;
    73 
    74     /**
    75      * Releases a read (shared) lock ackquired by lockRead().
    76      */
    77     virtual void unlockRead() = 0;
    78 
    79     // LockOps interface
    80     void lock() { lockRead(); }
    81     void unlock() { unlockRead(); }
    82 };
    83 
    84 /**
    85  * Write lock operations. See LockHandle and AutoWriteLock for details.
    86  */
    87 class WriteLockOps : public LockOps
    88 {
    89 public:
    90 
    91     /**
    92      * Requests a write (exclusive) lock.
    93      */
    94     virtual void lockWrite() = 0;
    95 
    96     /**
    97      * Releases a write (exclusive) lock ackquired by lockWrite().
    98      */
    99     virtual void unlockWrite() = 0;
    100 
    101     // LockOps interface
    102     void lock() { lockWrite(); }
    103     void unlock() { unlockWrite(); }
    104 };
    105 
    106 /**
    10750 * Abstract read/write semaphore handle.
    10851 *
     
    11457 * read and write locks.
    11558 */
    116 class LockHandle : protected ReadLockOps, protected WriteLockOps
    117 {
    118 public:
    119 
     59class LockHandle
     60{
     61public:
    12062    LockHandle() {}
    12163    virtual ~LockHandle() {}
     
    13779    virtual uint32_t writeLockLevel() const = 0;
    13880
    139     /**
    140      * Returns an interface to read lock operations of this semaphore.
    141      * Used by constructors of AutoMultiLockN classes.
    142      */
    143     LockOps *rlock() { return (ReadLockOps *) this; }
    144 
    145     /**
    146      * Returns an interface to write lock operations of this semaphore.
    147      * Used by constructors of AutoMultiLockN classes.
    148      */
    149     LockOps *wlock() { return (WriteLockOps *) this; }
     81    virtual void lockWrite() = 0;
     82    virtual void unlockWrite() = 0;
     83    virtual void lockRead() = 0;
     84    virtual void unlockRead() = 0;
    15085
    15186private:
    152 
    153     DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (LockHandle)
    154 
    155     friend class AutoWriteLockBase;
    156     friend class AutoWriteLock;
    157     friend class AutoReadLock;
     87    // prohibit copy + assignment
     88    LockHandle(const LockHandle&);
     89    LockHandle& operator=(const LockHandle&);
    15890};
    15991
     
    169101{
    170102public:
    171 
    172103    RWLockHandle();
    173104    virtual ~RWLockHandle();
    174105
    175     bool isWriteLockOnCurrentThread() const;
     106    virtual bool isWriteLockOnCurrentThread() const;
     107
     108    virtual void lockWrite();
     109    virtual void unlockWrite();
     110    virtual void lockRead();
     111    virtual void unlockRead();
     112
     113    virtual uint32_t writeLockLevel() const;
    176114
    177115private:
    178 
    179     DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (RWLockHandle)
    180 
    181     void lockWrite();
    182     void unlockWrite();
    183     void lockRead();
    184     void unlockRead();
    185 
    186     uint32_t writeLockLevel() const;
    187 
    188116    RTSEMRW mSemRW;
    189117};
     
    205133{
    206134public:
    207 
    208     WriteLockHandle()
    209     {
    210         RTCritSectInit (&mCritSect);
    211     }
    212 
    213     virtual ~WriteLockHandle()
    214     {
    215         RTCritSectDelete (&mCritSect);
    216     }
    217 
    218     bool isWriteLockOnCurrentThread() const
    219     {
    220         return RTCritSectIsOwner (&mCritSect);
    221     }
     135    WriteLockHandle();
     136    virtual ~WriteLockHandle();
     137    virtual bool isWriteLockOnCurrentThread() const;
     138
     139    virtual void lockWrite();
     140    virtual void unlockWrite();
     141    virtual void lockRead();
     142    virtual void unlockRead();
     143    virtual uint32_t writeLockLevel() const;
    222144
    223145private:
    224 
    225     DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (WriteLockHandle)
    226 
    227     void lockWrite()
    228     {
    229 #if defined(DEBUG)
    230         RTCritSectEnterDebug (&mCritSect,
    231                               "WriteLockHandle::lockWrite() return address >>>",
    232                               0, (RTUINTPTR) ASMReturnAddress());
    233 #else
    234         RTCritSectEnter (&mCritSect);
    235 #endif
    236     }
    237 
    238     void unlockWrite()
    239     {
    240         RTCritSectLeave (&mCritSect);
    241     }
    242 
    243     void lockRead() { lockWrite(); }
    244     void unlockRead() { unlockWrite(); }
    245 
    246     uint32_t writeLockLevel() const
    247     {
    248         return RTCritSectGetRecursion (&mCritSect);
    249     }
    250 
    251146    mutable RTCRITSECT mCritSect;
    252147};
     
    287182        return h ? h->isWriteLockOnCurrentThread() : false;
    288183    }
    289 
    290     /**
    291      * Equivalent to <tt>#lockHandle()->rlock()</tt>.
    292      * Returns @c NULL false if lockHandle() returns @c NULL.
    293      */
    294     LockOps *rlock()
    295     {
    296         LockHandle *h = lockHandle();
    297         return h ? h->rlock() : NULL;
    298     }
    299 
    300     /**
    301      * Equivalent to <tt>#lockHandle()->wlock()</tt>. Returns @c NULL false if
    302      * lockHandle() returns @c NULL.
    303      */
    304     LockOps *wlock()
    305     {
    306         LockHandle *h = lockHandle();
    307         return h ? h->wlock() : NULL;
    308     }
    309184};
    310185
     
    314189//
    315190////////////////////////////////////////////////////////////////////////////////
     191
     192/**
     193 * Abstract base class for all autolocks.
     194 *
     195 * This cannot be used directly. Use AutoReadLock or AutoWriteLock or AutoMultiWriteLock2/3
     196 * which directly and indirectly derive from this.
     197 *
     198 * In the implementation, the instance data contains a list of lock handles.
     199 * The class provides some utility functions to help locking and unlocking
     200 * them.
     201 */
    316202
    317203class AutoLockBase
     
    340226    // prohibit copy + assignment
    341227    AutoLockBase(const AutoLockBase&);
    342     AutoLockBase& operator=(AutoLockBase&);
     228    AutoLockBase& operator=(const AutoLockBase&);
    343229};
    344230
     
    349235////////////////////////////////////////////////////////////////////////////////
    350236
     237/**
     238 * Automatic read lock. Use this with a RWLockHandle to request a read/write
     239 * semaphore in read mode. You can also use this with a WriteLockHandle but
     240 * that makes little sense since they know no read mode.
     241 *
     242 * If constructed with a RWLockHandle or an instance of Lockable (which in
     243 * practice means any VirtualBoxBase derivative), it autoamtically requests
     244 * the lock in read mode and releases the read lock in the destructor.
     245 */
    351246class AutoReadLock : public AutoLockBase
    352247{
     
    417312////////////////////////////////////////////////////////////////////////////////
    418313
     314/**
     315 * Base class for all auto write locks.
     316 *
     317 * This cannot be used directly. Use AutoWriteLock or AutoMultiWriteLock2/3
     318 * which directly and indirectly derive from this.
     319 *
     320 * In addition to utility methods for subclasses, this implements the public
     321 * leave/enter/maybeLeave/maybeEnter methods, which are common to all
     322 * write locks.
     323 */
    419324class AutoWriteLockBase : public AutoLockBase
    420325{
     
    447352////////////////////////////////////////////////////////////////////////////////
    448353
     354/**
     355 * Automatic write lock. Use this with a RWLockHandle to request a read/write
     356 * semaphore in write mode. There can only ever be one writer of a read/write
     357 * semaphore: while the lock is held in write mode, no other writer or reader
     358 * can request the semaphore and will block.
     359 *
     360 * If constructed with a RWLockHandle or an instance of Lockable (which in
     361 * practice means any VirtualBoxBase derivative), it autoamtically requests
     362 * the lock in write mode and releases the write lock in the destructor.
     363 *
     364 * When used with a WriteLockHandle, it requests the semaphore contained therein
     365 * exclusively.
     366 */
    449367class AutoWriteLock : public AutoWriteLockBase
    450368{
     
    549467////////////////////////////////////////////////////////////////////////////////
    550468
     469/**
     470 * A multi-write-lock containing two other write locks.
     471 *
     472 */
    551473class AutoMultiWriteLock2 : public AutoWriteLockBase
    552474{
     
    561483};
    562484
     485/**
     486 * A multi-write-lock containing three other write locks.
     487 *
     488 */
    563489class AutoMultiWriteLock3 : public AutoWriteLockBase
    564490{
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette