VirtualBox

source: vbox/trunk/include/VBox/com/AutoLock.h

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.6 KB
RevLine 
[1]1/** @file
[58110]2 * MS COM / XPCOM Abstraction Layer - Automatic locks, implementation.
[1]3 */
4
5/*
[98103]6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[1]7 *
[96407]8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
[8155]10 *
[96407]11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
[25885]24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
[96407]26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
[25885]28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
[96407]32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
[1]34 */
35
[76558]36#ifndef VBOX_INCLUDED_com_AutoLock_h
37#define VBOX_INCLUDED_com_AutoLock_h
[76507]38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
[1]41
42#include <iprt/types.h>
43
[58110]44
45/** @defgroup grp_com_autolock Automatic Locks
46 * @ingroup grp_com
47 * @{
48 */
49
[25809]50// macros for automatic lock validation; these will amount to nothing
51// unless lock validation is enabled for the runtime
[26746]52#if defined(RT_LOCK_STRICT)
53# define VBOX_WITH_MAIN_LOCK_VALIDATION
[25310]54# define COMMA_LOCKVAL_SRC_POS , RT_SRC_POS
55# define LOCKVAL_SRC_POS_DECL RT_SRC_POS_DECL
56# define COMMA_LOCKVAL_SRC_POS_DECL , RT_SRC_POS_DECL
57# define LOCKVAL_SRC_POS_ARGS RT_SRC_POS_ARGS
58# define COMMA_LOCKVAL_SRC_POS_ARGS , RT_SRC_POS_ARGS
59#else
60# define COMMA_LOCKVAL_SRC_POS
61# define LOCKVAL_SRC_POS_DECL
62# define COMMA_LOCKVAL_SRC_POS_DECL
63# define LOCKVAL_SRC_POS_ARGS
64# define COMMA_LOCKVAL_SRC_POS_ARGS
65#endif
66
[1]67namespace util
68{
69
[25279]70////////////////////////////////////////////////////////////////////////////////
71//
[25809]72// Order classes for lock validation
73//
74////////////////////////////////////////////////////////////////////////////////
75
76/**
77 * IPRT now has a sophisticated system of run-time locking classes to validate
78 * locking order. Since the Main code is handled by simpler minds, we want
79 * compile-time constants for simplicity, and we'll look up the run-time classes
80 * in AutoLock.cpp transparently. These are passed to the constructors of the
81 * LockHandle classes.
82 */
[25834]83enum VBoxLockingClass
[25809]84{
85 LOCKCLASS_NONE = 0,
[30501]86 LOCKCLASS_WEBSERVICE = 1, // highest order: webservice locks
87 LOCKCLASS_VIRTUALBOXOBJECT = 2, // highest order within Main itself: VirtualBox object lock
88 LOCKCLASS_HOSTOBJECT = 3, // Host object lock
89 LOCKCLASS_LISTOFMACHINES = 4, // list of machines in VirtualBox object
90 LOCKCLASS_MACHINEOBJECT = 5, // Machine object lock
91 LOCKCLASS_SNAPSHOTOBJECT = 6, // snapshot object locks
[25930]92 // (the snapshots tree, including the child pointers in Snapshot,
93 // is protected by the normal Machine object lock)
[41528]94 LOCKCLASS_MEDIUMQUERY = 7, // lock used to protect Machine::queryInfo
95 LOCKCLASS_LISTOFMEDIA = 8, // list of media (hard disks, DVDs, floppies) in VirtualBox object
96 LOCKCLASS_LISTOFOTHEROBJECTS = 9, // any other list of objects
[38717]97 LOCKCLASS_OTHEROBJECT = 10, // any regular object member variable lock
[41528]98 LOCKCLASS_PROGRESSLIST = 11, // list of progress objects in VirtualBox; no other object lock
[25842]99 // may be held after this!
[90828]100 LOCKCLASS_OBJECTSTATE = 12, // object state lock (handled by AutoCaller classes)
101 LOCKCLASS_TRANSLATOR = 13 // translator internal lock
[25809]102};
103
104void InitAutoLockSystem();
105
[28270]106/**
107 * Check whether the current thread holds any locks in the given class
108 *
109 * @return true if any such locks are held, false otherwise. If the lock
110 * validator is not compiled in, always returns false.
111 * @param lockClass Which lock class to check.
112 */
113bool AutoLockHoldsLocksInClass(VBoxLockingClass lockClass);
114
[25809]115////////////////////////////////////////////////////////////////////////////////
116//
[25279]117// LockHandle and friends
118//
119////////////////////////////////////////////////////////////////////////////////
120
[7992]121/**
[25310]122 * Abstract base class for semaphore handles (RWLockHandle and WriteLockHandle).
[25408]123 * Don't use this directly, but this implements lock validation for them.
[7992]124 */
[25287]125class LockHandle
[7992]126{
127public:
[25809]128 LockHandle()
129 {}
[1]130
[25809]131 virtual ~LockHandle()
132 {}
133
[1]134 /**
[7992]135 * Returns @c true if the current thread holds a write lock on this
136 * read/write semaphore. Intended for debugging only.
[1]137 */
[8083]138 virtual bool isWriteLockOnCurrentThread() const = 0;
[7992]139
140 /**
[67721]141 * Returns @c true if the current thread holds a read lock on this
142 * read/write semaphore. Intended for debugging only as it isn't always
143 * accurate given @a fWannaHear.
144 */
145 virtual bool isReadLockedOnCurrentThread(bool fWannaHear = true) const = 0;
146
147 /**
[7992]148 * Returns the current write lock level of this semaphore. The lock level
[58106]149 * determines the number of nested #lockWrite() calls on the given
150 * semaphore handle.
[7992]151 *
152 * Note that this call is valid only when the current thread owns a write
153 * lock on the given semaphore handle and will assert otherwise.
154 */
155 virtual uint32_t writeLockLevel() const = 0;
156
[25408]157 virtual void lockWrite(LOCKVAL_SRC_POS_DECL) = 0;
158 virtual void unlockWrite() = 0;
159 virtual void lockRead(LOCKVAL_SRC_POS_DECL) = 0;
160 virtual void unlockRead() = 0;
161
[25834]162#ifdef VBOX_WITH_MAIN_LOCK_VALIDATION
[25408]163 virtual const char* describe() const = 0;
[25310]164#endif
165
[7992]166private:
[25287]167 // prohibit copy + assignment
168 LockHandle(const LockHandle&);
169 LockHandle& operator=(const LockHandle&);
[7992]170};
171
172/**
173 * Full-featured read/write semaphore handle implementation.
174 *
175 * This is an auxiliary base class for classes that need full-featured
[8083]176 * read/write locking as described in the AutoWriteLock class documentation.
[7992]177 * Instances of classes inherited from this class can be passed as arguments to
[8083]178 * the AutoWriteLock and AutoReadLock constructors.
[7992]179 */
180class RWLockHandle : public LockHandle
181{
182public:
[25834]183 RWLockHandle(VBoxLockingClass lockClass);
[7992]184 virtual ~RWLockHandle();
185
[25287]186 virtual bool isWriteLockOnCurrentThread() const;
[67721]187 virtual bool isReadLockedOnCurrentThread(bool fWannaHear = true) const;
[7992]188
[25310]189 virtual void lockWrite(LOCKVAL_SRC_POS_DECL);
[25287]190 virtual void unlockWrite();
[25310]191 virtual void lockRead(LOCKVAL_SRC_POS_DECL);
[25287]192 virtual void unlockRead();
[7992]193
[25287]194 virtual uint32_t writeLockLevel() const;
[7992]195
[25834]196#ifdef VBOX_WITH_MAIN_LOCK_VALIDATION
[25408]197 virtual const char* describe() const;
198#endif
199
[25287]200private:
[25288]201 struct Data;
202 Data *m;
[63147]203
204 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(RWLockHandle); /* Shuts up MSC warning C4625. */
[7992]205};
206
207/**
208 * Write-only semaphore handle implementation.
209 *
210 * This is an auxiliary base class for classes that need write-only (exclusive)
211 * locking and do not need read (shared) locking. This implementation uses a
212 * cheap and fast critical section for both lockWrite() and lockRead() methods
213 * which makes a lockRead() call fully equivalent to the lockWrite() call and
214 * therefore makes it pointless to use instahces of this class with
[8083]215 * AutoReadLock instances -- shared locking will not be possible anyway and
[7992]216 * any call to lock() will block if there are lock owners on other threads.
217 *
218 * Use with care only when absolutely sure that shared locks are not necessary.
219 */
220class WriteLockHandle : public LockHandle
221{
222public:
[25834]223 WriteLockHandle(VBoxLockingClass lockClass);
[25287]224 virtual ~WriteLockHandle();
225 virtual bool isWriteLockOnCurrentThread() const;
[67721]226 virtual bool isReadLockedOnCurrentThread(bool fWannaHear = true) const;
[7992]227
[25310]228 virtual void lockWrite(LOCKVAL_SRC_POS_DECL);
[25287]229 virtual void unlockWrite();
[25310]230 virtual void lockRead(LOCKVAL_SRC_POS_DECL);
[25287]231 virtual void unlockRead();
232 virtual uint32_t writeLockLevel() const;
[1]233
[25834]234#ifdef VBOX_WITH_MAIN_LOCK_VALIDATION
[25408]235 virtual const char* describe() const;
236#endif
237
[7992]238private:
[25288]239 struct Data;
240 Data *m;
[63147]241
242 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(WriteLockHandle); /* Shuts up MSC warning C4625. */
[7992]243};
[1]244
[25279]245////////////////////////////////////////////////////////////////////////////////
246//
247// Lockable
248//
249////////////////////////////////////////////////////////////////////////////////
250
[7992]251/**
252 * Lockable interface.
253 *
254 * This is an abstract base for classes that need read/write locking. Unlike
255 * RWLockHandle and other classes that makes the read/write semaphore a part of
256 * class data, this class allows subclasses to decide which semaphore handle to
257 * use.
258 */
259class Lockable
260{
261public:
[84342]262 virtual ~Lockable() { } /* To make VC++ 2019 happy. */
[7992]263
264 /**
[8083]265 * Returns a pointer to a LockHandle used by AutoWriteLock/AutoReadLock
266 * for locking. Subclasses are allowed to return @c NULL -- in this case,
267 * the AutoWriteLock/AutoReadLock object constructed using an instance of
[7992]268 * such subclass will simply turn into no-op.
269 */
270 virtual LockHandle *lockHandle() const = 0;
271
272 /**
[8083]273 * Equivalent to <tt>#lockHandle()->isWriteLockOnCurrentThread()</tt>.
[7992]274 * Returns @c false if lockHandle() returns @c NULL.
275 */
[8083]276 bool isWriteLockOnCurrentThread()
[7992]277 {
278 LockHandle *h = lockHandle();
[8083]279 return h ? h->isWriteLockOnCurrentThread() : false;
[7992]280 }
[67721]281
282 /**
283 * Equivalent to <tt>#lockHandle()->isReadLockedOnCurrentThread()</tt>.
284 * Returns @c false if lockHandle() returns @c NULL.
285 * @note Use with care, simple debug assertions and similar only.
286 */
[67722]287 bool isReadLockedOnCurrentThread(bool fWannaHear = true) const
[67721]288 {
289 LockHandle *h = lockHandle();
290 return h ? h->isReadLockedOnCurrentThread(fWannaHear) : false;
291 }
[7992]292};
293
[25279]294////////////////////////////////////////////////////////////////////////////////
295//
296// AutoLockBase
297//
298////////////////////////////////////////////////////////////////////////////////
299
[25287]300/**
301 * Abstract base class for all autolocks.
302 *
303 * This cannot be used directly. Use AutoReadLock or AutoWriteLock or AutoMultiWriteLock2/3
304 * which directly and indirectly derive from this.
305 *
306 * In the implementation, the instance data contains a list of lock handles.
307 * The class provides some utility functions to help locking and unlocking
308 * them.
309 */
310
[25279]311class AutoLockBase
[7992]312{
[25279]313protected:
[25310]314 AutoLockBase(uint32_t cHandles
315 COMMA_LOCKVAL_SRC_POS_DECL);
316 AutoLockBase(uint32_t cHandles,
317 LockHandle *pHandle
318 COMMA_LOCKVAL_SRC_POS_DECL);
[25281]319 virtual ~AutoLockBase();
[25279]320
[25281]321 struct Data;
322 Data *m;
323
[25283]324 virtual void callLockImpl(LockHandle &l) = 0;
325 virtual void callUnlockImpl(LockHandle &l) = 0;
[25282]326
[25283]327 void callLockOnAllHandles();
328 void callUnlockOnAllHandles();
329
330 void cleanup();
331
[25282]332public:
333 void acquire();
334 void release();
335
[25281]336private:
337 // prohibit copy + assignment
338 AutoLockBase(const AutoLockBase&);
[25287]339 AutoLockBase& operator=(const AutoLockBase&);
[25279]340};
341
342////////////////////////////////////////////////////////////////////////////////
343//
[25284]344// AutoReadLock
[25279]345//
346////////////////////////////////////////////////////////////////////////////////
347
[25287]348/**
349 * Automatic read lock. Use this with a RWLockHandle to request a read/write
350 * semaphore in read mode. You can also use this with a WriteLockHandle but
[25408]351 * that makes little sense since they treat read mode like write mode.
[25287]352 *
353 * If constructed with a RWLockHandle or an instance of Lockable (which in
354 * practice means any VirtualBoxBase derivative), it autoamtically requests
355 * the lock in read mode and releases the read lock in the destructor.
356 */
[25284]357class AutoReadLock : public AutoLockBase
[25279]358{
[7992]359public:
360
361 /**
362 * Constructs a null instance that does not manage any read/write
363 * semaphore.
364 *
365 * Note that all method calls on a null instance are no-ops. This allows to
366 * have the code where lock protection can be selected (or omitted) at
367 * runtime.
368 */
[25310]369 AutoReadLock(LOCKVAL_SRC_POS_DECL)
370 : AutoLockBase(1,
371 NULL
372 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]373 { }
[7992]374
375 /**
376 * Constructs a new instance that will start managing the given read/write
[25284]377 * semaphore by requesting a read lock.
[7992]378 */
[25310]379 AutoReadLock(LockHandle *aHandle
380 COMMA_LOCKVAL_SRC_POS_DECL)
381 : AutoLockBase(1,
382 aHandle
383 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]384 {
385 acquire();
386 }
[7992]387
388 /**
389 * Constructs a new instance that will start managing the given read/write
[25284]390 * semaphore by requesting a read lock.
[7992]391 */
[25310]392 AutoReadLock(LockHandle &aHandle
393 COMMA_LOCKVAL_SRC_POS_DECL)
394 : AutoLockBase(1,
395 &aHandle
396 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]397 {
398 acquire();
399 }
[7992]400
401 /**
402 * Constructs a new instance that will start managing the given read/write
[25284]403 * semaphore by requesting a read lock.
[7992]404 */
[25310]405 AutoReadLock(const Lockable &aLockable
406 COMMA_LOCKVAL_SRC_POS_DECL)
407 : AutoLockBase(1,
408 aLockable.lockHandle()
409 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]410 {
411 acquire();
412 }
[1]413
[7992]414 /**
415 * Constructs a new instance that will start managing the given read/write
[25284]416 * semaphore by requesting a read lock.
[7992]417 */
[25310]418 AutoReadLock(const Lockable *aLockable
419 COMMA_LOCKVAL_SRC_POS_DECL)
420 : AutoLockBase(1,
421 aLockable ? aLockable->lockHandle() : NULL
422 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]423 {
424 acquire();
425 }
[1]426
[25284]427 virtual ~AutoReadLock();
[25280]428
[25283]429 virtual void callLockImpl(LockHandle &l);
430 virtual void callUnlockImpl(LockHandle &l);
[63147]431
432private:
433 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoReadLock); /* Shuts up MSC warning C4625. */
[25284]434};
[25280]435
[25284]436////////////////////////////////////////////////////////////////////////////////
437//
438// AutoWriteLockBase
439//
440////////////////////////////////////////////////////////////////////////////////
441
[25287]442/**
443 * Base class for all auto write locks.
444 *
445 * This cannot be used directly. Use AutoWriteLock or AutoMultiWriteLock2/3
[25408]446 * which derive from this.
[25287]447 *
[40257]448 * It has some utility methods for subclasses.
[25287]449 */
[25284]450class AutoWriteLockBase : public AutoLockBase
451{
452protected:
[25310]453 AutoWriteLockBase(uint32_t cHandles
454 COMMA_LOCKVAL_SRC_POS_DECL)
455 : AutoLockBase(cHandles
456 COMMA_LOCKVAL_SRC_POS_ARGS)
[25284]457 { }
458
[25310]459 AutoWriteLockBase(uint32_t cHandles,
460 LockHandle *pHandle
461 COMMA_LOCKVAL_SRC_POS_DECL)
462 : AutoLockBase(cHandles,
463 pHandle
464 COMMA_LOCKVAL_SRC_POS_ARGS)
[25285]465 { }
466
[25284]467 virtual ~AutoWriteLockBase()
468 { }
469
470 virtual void callLockImpl(LockHandle &l);
471 virtual void callUnlockImpl(LockHandle &l);
[63147]472
473private:
474 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoWriteLockBase); /* Shuts up MSC warning C4625. */
[7992]475};
476
477////////////////////////////////////////////////////////////////////////////////
[25279]478//
[25284]479// AutoWriteLock
[25279]480//
481////////////////////////////////////////////////////////////////////////////////
[7992]482
[25287]483/**
484 * Automatic write lock. Use this with a RWLockHandle to request a read/write
485 * semaphore in write mode. There can only ever be one writer of a read/write
486 * semaphore: while the lock is held in write mode, no other writer or reader
487 * can request the semaphore and will block.
488 *
489 * If constructed with a RWLockHandle or an instance of Lockable (which in
490 * practice means any VirtualBoxBase derivative), it autoamtically requests
491 * the lock in write mode and releases the write lock in the destructor.
492 *
493 * When used with a WriteLockHandle, it requests the semaphore contained therein
494 * exclusively.
495 */
[25284]496class AutoWriteLock : public AutoWriteLockBase
[7992]497{
498public:
499
[3329]500 /**
[7992]501 * Constructs a null instance that does not manage any read/write
502 * semaphore.
503 *
504 * Note that all method calls on a null instance are no-ops. This allows to
505 * have the code where lock protection can be selected (or omitted) at
506 * runtime.
[3329]507 */
[25310]508 AutoWriteLock(LOCKVAL_SRC_POS_DECL)
509 : AutoWriteLockBase(1,
510 NULL
511 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]512 { }
[3329]513
514 /**
[7992]515 * Constructs a new instance that will start managing the given read/write
[25284]516 * semaphore by requesting a write lock.
[3329]517 */
[25310]518 AutoWriteLock(LockHandle *aHandle
519 COMMA_LOCKVAL_SRC_POS_DECL)
520 : AutoWriteLockBase(1,
521 aHandle
522 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]523 {
524 acquire();
525 }
[3329]526
[7992]527 /**
528 * Constructs a new instance that will start managing the given read/write
[25284]529 * semaphore by requesting a write lock.
[7992]530 */
[25310]531 AutoWriteLock(LockHandle &aHandle
532 COMMA_LOCKVAL_SRC_POS_DECL)
533 : AutoWriteLockBase(1,
534 &aHandle
535 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]536 {
537 acquire();
538 }
[1]539
[7992]540 /**
541 * Constructs a new instance that will start managing the given read/write
[25284]542 * semaphore by requesting a write lock.
[7992]543 */
[25310]544 AutoWriteLock(const Lockable &aLockable
545 COMMA_LOCKVAL_SRC_POS_DECL)
546 : AutoWriteLockBase(1,
547 aLockable.lockHandle()
548 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]549 {
550 acquire();
551 }
[1]552
[7992]553 /**
554 * Constructs a new instance that will start managing the given read/write
[25284]555 * semaphore by requesting a write lock.
[7992]556 */
[25310]557 AutoWriteLock(const Lockable *aLockable
558 COMMA_LOCKVAL_SRC_POS_DECL)
559 : AutoWriteLockBase(1,
560 aLockable ? aLockable->lockHandle() : NULL
561 COMMA_LOCKVAL_SRC_POS_ARGS)
[25279]562 {
563 acquire();
564 }
[7992]565
[25284]566 /**
[38773]567 * Constructs a new instance that will start managing the given read/write
568 * semaphore by requesting a write lock.
569 */
570 AutoWriteLock(uint32_t cHandles,
571 LockHandle** pHandles
572 COMMA_LOCKVAL_SRC_POS_DECL);
573
574 /**
[58106]575 * Release all write locks acquired by this instance through the #acquire()
[25284]576 * call and destroys the instance.
577 *
[58106]578 * Note that if there there are nested #acquire() calls without the
579 * corresponding number of #release() calls when the destructor is called, it
[25284]580 * will assert. This is because having an unbalanced number of nested locks
581 * is a program logic error which must be fixed.
582 */
583 virtual ~AutoWriteLock()
584 {
585 cleanup();
586 }
[1]587
[25284]588 void attach(LockHandle *aHandle);
589
590 /** @see attach (LockHandle *) */
591 void attach(LockHandle &aHandle)
592 {
593 attach(&aHandle);
594 }
595
596 /** @see attach (LockHandle *) */
597 void attach(const Lockable &aLockable)
598 {
599 attach(aLockable.lockHandle());
600 }
601
602 /** @see attach (LockHandle *) */
603 void attach(const Lockable *aLockable)
604 {
605 attach(aLockable ? aLockable->lockHandle() : NULL);
606 }
607
[25285]608 bool isWriteLockOnCurrentThread() const;
609 uint32_t writeLockLevel() const;
[63147]610
[67721]611 bool isReadLockedOnCurrentThread(bool fWannaHear = true) const;
612
[63147]613private:
614 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoWriteLock); /* Shuts up MSC warning C4625. */
[1]615};
616
[7992]617////////////////////////////////////////////////////////////////////////////////
[25279]618//
[25285]619// AutoMultiWriteLock*
620//
621////////////////////////////////////////////////////////////////////////////////
622
[25287]623/**
624 * A multi-write-lock containing two other write locks.
625 *
626 */
[25285]627class AutoMultiWriteLock2 : public AutoWriteLockBase
628{
629public:
[25310]630 AutoMultiWriteLock2(Lockable *pl1,
631 Lockable *pl2
632 COMMA_LOCKVAL_SRC_POS_DECL);
633 AutoMultiWriteLock2(LockHandle *pl1,
634 LockHandle *pl2
635 COMMA_LOCKVAL_SRC_POS_DECL);
[25285]636
637 virtual ~AutoMultiWriteLock2()
638 {
639 cleanup();
640 }
[63147]641
642private:
643 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoMultiWriteLock2); /* Shuts up MSC warning C4625. */
[25285]644};
645
[25287]646/**
647 * A multi-write-lock containing three other write locks.
648 *
649 */
[25285]650class AutoMultiWriteLock3 : public AutoWriteLockBase
651{
652public:
[25310]653 AutoMultiWriteLock3(Lockable *pl1,
654 Lockable *pl2,
655 Lockable *pl3
656 COMMA_LOCKVAL_SRC_POS_DECL);
657 AutoMultiWriteLock3(LockHandle *pl1,
658 LockHandle *pl2,
659 LockHandle *pl3
660 COMMA_LOCKVAL_SRC_POS_DECL);
[25285]661
662 virtual ~AutoMultiWriteLock3()
663 {
664 cleanup();
665 }
[63147]666
667private:
668 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoMultiWriteLock3); /* Shuts up MSC warning C4625. */
[25285]669};
670
[38743]671/**
672 * A multi-write-lock containing four other write locks.
673 *
674 */
675class AutoMultiWriteLock4 : public AutoWriteLockBase
676{
677public:
678 AutoMultiWriteLock4(Lockable *pl1,
679 Lockable *pl2,
680 Lockable *pl3,
681 Lockable *pl4
682 COMMA_LOCKVAL_SRC_POS_DECL);
683 AutoMultiWriteLock4(LockHandle *pl1,
684 LockHandle *pl2,
685 LockHandle *pl3,
686 LockHandle *pl4
687 COMMA_LOCKVAL_SRC_POS_DECL);
688
689 virtual ~AutoMultiWriteLock4()
690 {
691 cleanup();
692 }
[63147]693
694private:
695 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoMultiWriteLock4); /* Shuts up MSC warning C4625. */
[38743]696};
697
[5658]698} /* namespace util */
[1]699
[58110]700/** @} */
701
[76585]702#endif /* !VBOX_INCLUDED_com_AutoLock_h */
[1]703
[14949]704/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use