Changeset 25286 in vbox for trunk/src/VBox/Main/include/AutoLock.h
- Timestamp:
- Dec 9, 2009 11:50:02 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 55833
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/AutoLock.h
r25285 r25286 573 573 }; 574 574 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 AutoMultiLockBase589 {590 public:591 592 /**593 * Releases all locks if not yet released by #unlock() and destroys the594 * instance.595 */596 ~AutoMultiLockBase()597 {598 if (mIsLocked)599 unlock();600 }601 602 /**603 * Calls LockOps::lock() methods of all managed semaphore handles604 * in order they were passed to the constructor.605 *606 * Note that as opposed to LockHandle::lock(), this call cannot be nested607 * 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 in622 * reverse to the order they were passed to the constructor.623 *624 * Note that as opposed to LockHandle::unlock(), this call cannot be nested625 * 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 do634 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##n666 #define B(n) mOps [n] = l##n667 668 /**669 * AutoMultiLock for 2 locks.670 *671 * The AutoMultiLockN family of classes provides a possibility to manage several672 * read/write semaphores at once. This is handy if all managed semaphores need673 * to be locked and unlocked synchronously and will also help to avoid locking674 * order errors.675 *676 * Instances of AutoMultiLockN classes are constructed from a list of LockOps677 * arguments. The AutoMultiLockBase::lock() method will make sure that the given678 * list of semaphores represented by LockOps pointers will be locked in order679 * they are passed to the constructor. The AutoMultiLockBase::unlock() method680 * 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 individually683 * 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 here699 * </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 B725 #undef A726 727 575 } /* namespace util */ 728 576
Note:
See TracChangeset
for help on using the changeset viewer.