VirtualBox

source: vbox/trunk/src/VBox/Main/include/ObjectState.h@ 53390

Last change on this file since 53390 was 51903, checked in by vboxsync, 10 years ago

Main: AutoCaller/VirtualBoxBase refactoring, cleanly splitting out the object state handling, and moving all caller synchronization to one file. Also eliminated a not so vital template (AutoCallerBase) by much simpler inheritance. Theoretically has no visible effects, the behavior should be identical. Done as a preparation for reimplementing the caller synchronization.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.8 KB
Line 
1/** @file
2 *
3 * VirtualBox object state handling definitions
4 */
5
6/*
7 * Copyright (C) 2006-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ____H_OBJECTSTATE
19#define ____H_OBJECTSTATE
20
21#include "VBox/com/defs.h"
22#include "VBox/com/AutoLock.h"
23
24// Forward declaration needed, but nothing more.
25class VirtualBoxBase;
26
27////////////////////////////////////////////////////////////////////////////////
28//
29// ObjectState
30//
31////////////////////////////////////////////////////////////////////////////////
32
33/**
34 * Thec functionality implemented by this class is the primary object state
35 * (used by VirtualBoxBase and thus part of all API classes) that indicates
36 * if the object is ready to serve the calls, and if not, what stage it is
37 * currently at. Here is the primary state diagram:
38 *
39 * +-------------------------------------------------------+
40 * | |
41 * | (InitFailed) -----------------------+ |
42 * | ^ | |
43 * v | v |
44 * [*] ---> NotReady ----> (InInit) -----> Ready -----> (InUninit) ----+
45 * ^ |
46 * | v
47 * | Limited
48 * | |
49 * +-------+
50 *
51 * The object is fully operational only when its state is Ready. The Limited
52 * state means that only some vital part of the object is operational, and it
53 * requires some sort of reinitialization to become fully operational. The
54 * NotReady state means the object is basically dead: it either was not yet
55 * initialized after creation at all, or was uninitialized and is waiting to be
56 * destroyed when the last reference to it is released. All other states are
57 * transitional.
58 *
59 * The NotReady->InInit->Ready, NotReady->InInit->Limited and
60 * NotReady->InInit->InitFailed transition is done by the AutoInitSpan smart
61 * class.
62 *
63 * The Limited->InInit->Ready, Limited->InInit->Limited and
64 * Limited->InInit->InitFailed transition is done by the AutoReinitSpan smart
65 * class.
66 *
67 * The Ready->InUninit->NotReady and InitFailed->InUninit->NotReady
68 * transitions are done by the AutoUninitSpan smart class.
69 *
70 * In order to maintain the primary state integrity and declared functionality
71 * the following rules apply everywhere:
72 *
73 * 1) Use the above Auto*Span classes to perform state transitions. See the
74 * individual class descriptions for details.
75 *
76 * 2) All public methods of subclasses (i.e. all methods that can be called
77 * directly, not only from within other methods of the subclass) must have a
78 * standard prolog as described in the AutoCaller and AutoLimitedCaller
79 * documentation. Alternatively, they must use #addCaller() and
80 * #releaseCaller() directly (and therefore have both the prolog and the
81 * epilog), but this is not recommended because it is easy to forget the
82 * matching release, e.g. returning before reaching the call.
83 */
84class ObjectState
85{
86public:
87 enum State { NotReady, Ready, InInit, InUninit, InitFailed, Limited };
88
89 ObjectState(VirtualBoxBase *aObj);
90 ~ObjectState();
91
92 State getState();
93
94 HRESULT addCaller(bool aLimited = false);
95 void releaseCaller();
96
97 bool autoInitSpanConstructor(State aExpectedState);
98 void autoInitSpanDestructor(State aNewState);
99 State autoUninitSpanConstructor();
100 void autoUninitSpanDestructor();
101
102private:
103 ObjectState();
104
105 void setState(State aState);
106
107 /** Pointer to the managed object, mostly for error signalling or debugging
108 * purposes, not used much. Guaranteed to be valid during the lifetime of
109 * this object, no need to mess with refcount. */
110 VirtualBoxBase *mObj;
111 /** Primary state of this object */
112 State mState;
113 /** Thread that caused the last state change */
114 RTTHREAD mStateChangeThread;
115 /** Total number of active calls to this object */
116 unsigned mCallers;
117 /** Posted when the number of callers drops to zero */
118 RTSEMEVENT mZeroCallersSem;
119 /** Posted when the object goes from InInit/InUninit to some other state */
120 RTSEMEVENTMULTI mInitUninitSem;
121 /** Number of threads waiting for mInitUninitDoneSem */
122 unsigned mInitUninitWaiters;
123
124 /** Protects access to state related data members */
125 util::RWLockHandle mStateLock;
126};
127
128#endif // !____H_OBJECTSTATE
Note: See TracBrowser for help on using the repository browser.

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