VirtualBox

Ignore:
Timestamp:
Dec 9, 2009 11:50:02 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
55833
Message:

Main: preparation for deadlock detection: remove AutoMultiLock* template

File:
1 edited

Legend:

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

    r25285 r25286  
    573573};
    574574
    575 
    576 ////////////////////////////////////////////////////////////////////////////////
    577 //
    578 // AutoMulti*
    579 //
    580 ////////////////////////////////////////////////////////////////////////////////
    581 
    582 /**
    583  * Helper template class for AutoMultiLockN classes.
    584  *
    585  * @param Cnt number of read/write semaphores to manage.
    586  */
    587 template <size_t Cnt>
    588 class AutoMultiLockBase
    589 {
    590 public:
    591 
    592     /**
    593      * Releases all locks if not yet released by #unlock() and destroys the
    594      * instance.
    595      */
    596     ~AutoMultiLockBase()
    597     {
    598         if (mIsLocked)
    599             unlock();
    600     }
    601 
    602     /**
    603      * Calls LockOps::lock() methods of all managed semaphore handles
    604      * in order they were passed to the constructor.
    605      *
    606      * Note that as opposed to LockHandle::lock(), this call cannot be nested
    607      * and will assert if so.
    608      */
    609     void lock()
    610     {
    611         AssertReturnVoid (!mIsLocked);
    612 
    613         size_t i = 0;
    614         while (i < RT_ELEMENTS (mOps))
    615             if (mOps [i])
    616                 mOps [i ++]->lock();
    617         mIsLocked = true;
    618     }
    619 
    620     /**
    621      * Calls LockOps::unlock() methods of all managed semaphore handles in
    622      * reverse to the order they were passed to the constructor.
    623      *
    624      * Note that as opposed to LockHandle::unlock(), this call cannot be nested
    625      * and will assert if so.
    626      */
    627     void unlock()
    628     {
    629         AssertReturnVoid (mIsLocked);
    630 
    631         AssertReturnVoid (RT_ELEMENTS (mOps) > 0);
    632         size_t i = RT_ELEMENTS (mOps);
    633         do
    634             if (mOps [-- i])
    635                 mOps [i]->unlock();
    636         while (i != 0);
    637         mIsLocked = false;
    638     }
    639 
    640 protected:
    641 
    642     AutoMultiLockBase() : mIsLocked (false) {}
    643 
    644     LockOps *mOps [Cnt];
    645     bool mIsLocked;
    646 
    647 private:
    648 
    649     DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (AutoMultiLockBase)
    650     DECLARE_CLS_NEW_DELETE_NOOP (AutoMultiLockBase)
    651 };
    652 
    653 /** AutoMultiLockBase <0> is meaningless and forbidden. */
    654 template<>
    655 class AutoMultiLockBase <0> { private : AutoMultiLockBase(); };
    656 
    657 /** AutoMultiLockBase <1> is meaningless and forbidden. */
    658 template<>
    659 class AutoMultiLockBase <1> { private : AutoMultiLockBase(); };
    660 
    661 ////////////////////////////////////////////////////////////////////////////////
    662 
    663 /* AutoMultiLockN class definitions */
    664 
    665 #define A(n) LockOps *l##n
    666 #define B(n) mOps [n] = l##n
    667 
    668 /**
    669  * AutoMultiLock for 2 locks.
    670  *
    671  * The AutoMultiLockN family of classes provides a possibility to manage several
    672  * read/write semaphores at once. This is handy if all managed semaphores need
    673  * to be locked and unlocked synchronously and will also help to avoid locking
    674  * order errors.
    675  *
    676  * Instances of AutoMultiLockN classes are constructed from a list of LockOps
    677  * arguments. The AutoMultiLockBase::lock() method will make sure that the given
    678  * list of semaphores represented by LockOps pointers will be locked in order
    679  * they are passed to the constructor. The AutoMultiLockBase::unlock() method
    680  * will make sure that they will be unlocked in reverse order.
    681  *
    682  * The type of the lock to request is specified for each semaphore individually
    683  * using the corresponding LockOps getter of a LockHandle or Lockable object:
    684  * LockHandle::wlock() in order to request a write lock or LockHandle::rlock()
    685  * in order to request a read lock.
    686  *
    687  * Here is a typical usage pattern:
    688  * <code>
    689  *  ...
    690  *  LockHandle data1, data2;
    691  *  ...
    692  *  {
    693  *      AutoMultiLock2 multiLock (data1.wlock(), data2.rlock());
    694  *      // both locks are held here:
    695  *      // - data1 is locked in write mode (like AutoWriteLock)
    696  *      // - data2 is locked in read mode (like AutoReadLock)
    697  *  }
    698  *  // both locks are released here
    699  * </code>
    700  */
    701 class AutoMultiLock2 : public AutoMultiLockBase <2>
    702 {
    703 public:
    704     AutoMultiLock2 (A(0), A(1))
    705     { B(0); B(1); lock(); }
    706 };
    707 
    708 /** AutoMultiLock for 3 locks. See AutoMultiLock2 for more information. */
    709 class AutoMultiLock3 : public AutoMultiLockBase <3>
    710 {
    711 public:
    712     AutoMultiLock3 (A(0), A(1), A(2))
    713     { B(0); B(1); B(2); lock(); }
    714 };
    715 
    716 /** AutoMultiLock for 4 locks. See AutoMultiLock2 for more information. */
    717 class AutoMultiLock4 : public AutoMultiLockBase <4>
    718 {
    719 public:
    720     AutoMultiLock4 (A(0), A(1), A(2), A(3))
    721     { B(0); B(1); B(2); B(3); lock(); }
    722 };
    723 
    724 #undef B
    725 #undef A
    726 
    727575} /* namespace util */
    728576
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