1 // Copyright 2007, Google Inc.
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
6 // 1. Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright notice,
9 // this list of conditions and the following disclaimer in the documentation
10 // and/or other materials provided with the distribution.
11 // 3. Neither the name of Google Inc. nor the names of its contributors may be
12 // used to endorse or promote products derived from this software without
13 // specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef GEARS_BASE_COMMON_MUTEX_H__
27 #define GEARS_BASE_COMMON_MUTEX_H__
29 #include "gears/base/common/common.h" // for DISALLOW_EVIL_CONSTRUCTORS
31 // TODO(mpcomplete): implement these.
32 #if BROWSER_NPAPI && defined(WIN32)
39 // A Mutex is a non-reentrant (aka non-recursive) mutex. At most
40 // one thread T may hold a mutex at a given time.
41 // See also MutexLock, below, for scoped Mutex acquisition.
51 // Until the Condition is true, releases and reacquires this Mutex.
52 // The thread must already hold this Mutex when calling Await().
53 // Performance matches that of native Events (Win32) or CondVars (Firefox).
55 // A Condition "cond" used with this Mutex may be invoked an arbitrary
56 // number of times, by any thread using the Mutex. "cond" will always
57 // be invoked with the Mutex held by the thread that calls it, so it
58 // should not block for long periods or sleep on a timer. "cond" must return
59 // a boolean that is a function of state that is protected by the Mutex. Thus,
60 // if "cond" returns true just before this Mutex is released, it must also
61 // return true just after this Mutex is reacquired. "cond" MUST NOT BE A
62 // FUNCTION OF THE TIME, or of any other state not protected by the Mutex!
63 void Await(const Condition
&cond
);
71 CRITICAL_SECTION crit_sec_
;
75 pthread_mutex_t mutex_
;
80 // ----------------------------------------------------------------------------
83 // MutexLock(mu) acquires mu when constructed and releases it when destroyed.
87 explicit MutexLock(Mutex
*mu
) : mu_(mu
) { this->mu_
->Lock(); }
88 ~MutexLock() { this->mu_
->Unlock(); }
91 DISALLOW_EVIL_CONSTRUCTORS(MutexLock
);
93 // Catch bug where variable name is omitted, e.g. MutexLock (&mu);
94 #define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
97 // ----------------------------------------------------------------------------
100 // Implements a subset of the Google 'Condition' class.
102 // Any variables referenced to evaluate this Condition should be protected by
103 // the Mutex receiving this Condition.
105 // Various calls in Mutex take a Condition as argument;
106 // clients can wait for conditions to become true.
107 // Functions passed to the constructors should be pure functions;
108 // their results should depend only on the arguments and
109 // they should have no side-effects.
113 // A Condition that returns the value of *cond.
114 explicit Condition(bool *cond
)
115 : function_(reinterpret_cast<InternalFunctionType
>(Dereference
)),
118 // Templated versions for invoking a method that returns a bool.
119 // Usage: Condition(object, &Class::Method)
120 // Condition::Eval() returns the result of object->Method()
122 Condition(T
*object
, bool (T::*method
)());
123 // Same as above, for const members
125 Condition(const T
*object
, bool (T::*method
)() const);
127 // Evaluates the condition
130 InternalMethodCallerType caller
=
131 reinterpret_cast<InternalMethodCallerType
>(function_
);
132 return (*caller
)(arg_
, method_
);
134 return function_
== 0 || (*function_
)(arg_
);
138 typedef bool (*InternalFunctionType
)(void *);
139 typedef bool (Condition::*InternalMethodType
)();
140 typedef bool (*InternalMethodCallerType
)(void *, InternalMethodType
);
142 static bool Dereference(bool *arg
) { return *arg
; }
145 static bool ConditionMethodCaller(void *v
, bool (Condition::*m
)());
147 InternalFunctionType function_
; // function taking void * returning bool
148 InternalMethodType method_
; // method returning bool
154 bool Condition::ConditionMethodCaller(void *v
, bool (Condition::*m
)()) {
155 typedef bool (T::*RealMethodType
)();
156 T
*x
= static_cast<T
*>(v
);
157 RealMethodType rm
= reinterpret_cast<RealMethodType
>(m
);
162 inline Condition::Condition(T
*object
, bool (T::*method
)()) :
163 method_(reinterpret_cast<InternalMethodType
>(method
)), arg_(object
) {
164 InternalMethodCallerType caller
= &ConditionMethodCaller
<T
>;
165 this->function_
= reinterpret_cast<InternalFunctionType
>(caller
);
169 inline Condition::Condition(const T
*object
, bool (T::*method
)() const) :
170 method_((InternalMethodType
) method
), arg_((void *) object
) {
171 InternalMethodCallerType caller
= &ConditionMethodCaller
<T
>;
172 this->function_
= reinterpret_cast<InternalFunctionType
>(caller
);
175 // TODO(mpcomplete): remove
180 #endif // GEARS_BASE_COMMON_MUTEX_H__