Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: base/synchronized.h

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/string_unittest.cc ('k') | base/synchronized.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2004-2010 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // Declares some classes and macros to encapsulate
17 // the synchronization primitives.
18
19 // TODO(omaha): remove dependency on atlstr
20
21 #ifndef OMAHA_BASE_SYNCHRONIZED_H_
22 #define OMAHA_BASE_SYNCHRONIZED_H_
23
24 #include <windows.h>
25 #include <atlstr.h>
26 #include "base/basictypes.h"
27
28 namespace omaha {
29
30 // This macros are used to create a unique name
31 // We need to go through two steps of expansion.
32 // Macro kMakeName1 will expand to string + number
33 // and macro kMakeName1 will put them together to create
34 // the unique name.
35 #define MAKE_NAME2(x, y) x##y
36 #define MAKE_NAME1(x, y) MAKE_NAME2(x, y)
37 #define MAKE_NAME(x) MAKE_NAME1(x, __COUNTER__)
38
39 // Declare the interface in implement mutual
40 // exclusion. For in process mutual exclusion
41 // simple critical sections can be used. For
42 // interprocess mutual exclusion some named
43 // kernel mode object will have to be used.
44 struct Lockable {
45 virtual ~Lockable() {}
46 virtual bool Lock() const = 0;
47 virtual bool Unlock() const = 0;
48 };
49
50 // Scope based mutual exclusion. Locks
51 // the object on construction and unlocks
52 // during destruction. Very convinient to use
53 // with the macros __mutexScope and __mutexBlock
54 class AutoSync {
55 bool first_time_;
56 public:
57 explicit AutoSync(const Lockable *pLock);
58 explicit AutoSync(const Lockable &rLock);
59 ~AutoSync();
60 // this function is only needed to use with
61 // the macro __mutexBlock
62 bool FirstTime();
63 private:
64 const Lockable * lock_;
65 DISALLOW_EVIL_CONSTRUCTORS(AutoSync);
66 };
67
68 // the usaage:
69 // class A : public Lockable {
70 //
71 //
72 //
73 // void foo(){
74 // __mutexScope(this);
75 // ......
76 // .......
77 // everything is synchronized till the end of the
78 // function or the time it returns (from any place)
79 // } // end foo.
80 //
81 // void bar() {
82 // ......
83 // ...... do something here.
84 // ......
85 // __mutexBlock(this){
86 // .... do some other stuff
87 // ....
88 // ....
89 // } everything is synchronized till here
90 //
91 // }; // end class A
92
93 //
94 #define __mutexScope(lock) AutoSync MAKE_NAME(hiddenLock)(lock)
95 #define __mutexBlock(lock) \
96 for (AutoSync hiddenLock(lock); hiddenLock.FirstTime(); )
97
98 // GLock stands for global lock.
99 // Implementaion of Lockable to allow mutual exclusion
100 // between different processes.
101 // For in-process mutual exclusion use LLock - local lock
102 class GLock : public Lockable {
103 public:
104 GLock();
105 virtual ~GLock();
106
107 // Create mutex returns the status of creation. Use ::GetLastError for
108 // error information.
109 bool InitializeWithSecAttr(const TCHAR* name,
110 LPSECURITY_ATTRIBUTES lock_attributes);
111
112 // Create mutex return the status of creation. Sets to default DACL.
113 bool Initialize(const TCHAR* name);
114
115 virtual bool Lock() const;
116 virtual bool Lock(DWORD dwMilliseconds) const;
117 virtual bool Unlock() const;
118
119 private:
120 #if defined(DEBUG) || defined(ASSERT_IN_RELEASE)
121 CString name_;
122 #endif
123 mutable HANDLE mutex_;
124 DISALLOW_EVIL_CONSTRUCTORS(GLock);
125 };
126
127 // FakeGLock looks like a GLock, but none of its methods do anything.
128 // Only used with SharedMemoryPtr, in cases where locking is not required or
129 // desired.
130 class FakeGLock : public Lockable {
131 public:
132 FakeGLock() {}
133 virtual ~FakeGLock() {}
134 bool InitializeWithSecAttr(const TCHAR*, LPSECURITY_ATTRIBUTES) {
135 return true;
136 }
137 bool Initialize(const TCHAR*) { return true; }
138 virtual bool Lock() const { return true; }
139 virtual bool Lock(DWORD) const { return true; }
140 virtual bool Unlock() const { return true; }
141
142 private:
143 DISALLOW_EVIL_CONSTRUCTORS(FakeGLock);
144 };
145
146 // LLock stands for local lock.
147 // means works only inside the process.
148 // use GLock - global lock for inter-process
149 // guarded access to data.
150 class LLock : public Lockable {
151 public:
152 LLock();
153 virtual ~LLock();
154 virtual bool Lock() const;
155 virtual bool Lock(DWORD wait_ms) const;
156 virtual bool Unlock() const;
157
158 // Returns the thread id of the owner or 0 if the lock is not owned.
159 DWORD GetOwner() const;
160 private:
161 mutable CRITICAL_SECTION critical_section_;
162 DISALLOW_EVIL_CONSTRUCTORS(LLock);
163 };
164
165 // A gate is a synchronization object used to either stop all
166 // threads from proceeding through a point or to allow them all to proceed.
167 class Gate {
168 public:
169 // In process gate.
170 Gate();
171
172 // Interprocess gate.
173 explicit Gate(const TCHAR * event_name);
174
175 ~Gate();
176
177 // Open the gate.
178 bool Open();
179
180 // Close the gate.
181 bool Close();
182
183 // Wait to enter the gate.
184 bool Wait(DWORD msec);
185
186 // Conversion from the object to a HANDLE.
187 operator HANDLE() const {return gate_;}
188
189 // Returns S_OK, and sets selected_gate to zero based index of the gate that
190 // was opened.
191 // Returns E_FAIL if timeout occured or gate was abandoned.
192 static HRESULT WaitAny(Gate const * const *gates,
193 int num_gates,
194 DWORD msec,
195 int *selected_gate);
196
197 // Returns S_OK if all gates were opened
198 // Returns E_FAIL if timeout occured or gate was abandoned.
199 static HRESULT WaitAll(Gate const * const *gates, int num_gates, DWORD msec);
200
201 private:
202 bool Initialize(const TCHAR * event_name);
203 static HRESULT WaitMultipleHelper(Gate const * const *gates,
204 int num_gates,
205 DWORD msec,
206 int *selected_gate,
207 bool wait_all);
208 HANDLE gate_;
209 DISALLOW_EVIL_CONSTRUCTORS(Gate);
210 };
211
212 bool WaitAllowRepaint(const Gate& gate, DWORD msec);
213
214 class AutoGateKeeper {
215 public:
216 explicit AutoGateKeeper(Gate *gate) : gate_(gate) {
217 gate_->Open();
218 }
219 ~AutoGateKeeper() {
220 gate_->Close();
221 }
222 private:
223 Gate *gate_;
224 DISALLOW_EVIL_CONSTRUCTORS(AutoGateKeeper);
225 };
226
227 // A very simple rather fast lock - if uncontested. USE ONLY AS A GLOBAL OBJECT
228 // (i.e., DECLARED AT FILE SCOPE or as a STATIC CLASS MEMBER) - this is not
229 // enforced. Uses interlocked instructions on an int to get a fast user-mode
230 // lock. (Locks the bus and does a couple of memory references so it isn't
231 // free.) Spin-waits to get the lock. Has the advantage that it needs no
232 // initialization - thus has no order-of-evaluation problems with respect to
233 // other global objects. Does not work (causes deadlock) if locked twice by
234 // the same thread. (Has no constructor so is initialized to 0 by C++.
235 // This is why it must be a global or static class member: it doesn't initialize
236 // itself to 0. This is also why it doesn't inherit from Lockable, which would
237 // make it need to initialize a virtual table.)
238 struct SimpleLock {
239 bool Lock() const;
240 bool Unlock() const;
241 private:
242 mutable volatile long lock_;
243 };
244
245 struct SimpleLockWithDelay {
246 bool Lock() const;
247 bool Unlock() const;
248 private:
249 mutable volatile long lock_;
250 };
251
252 class AutoSimpleLock {
253 public:
254 explicit AutoSimpleLock(const SimpleLock& lock)
255 : lock_(lock) { lock_.Lock(); }
256 ~AutoSimpleLock() { lock_.Unlock(); }
257 private:
258 const SimpleLock& lock_;
259 DISALLOW_EVIL_CONSTRUCTORS(AutoSimpleLock);
260 };
261
262 class AutoSimpleLockWithDelay {
263 public:
264 explicit AutoSimpleLockWithDelay(const SimpleLockWithDelay& lock)
265 : lock_(lock) { lock_.Lock(); }
266 ~AutoSimpleLockWithDelay() { lock_.Unlock(); }
267 private:
268 const SimpleLockWithDelay& lock_;
269 DISALLOW_EVIL_CONSTRUCTORS(AutoSimpleLockWithDelay);
270 };
271
272
273 // allow only one thread to hold a lock
274 class CriticalSection {
275 public:
276 CriticalSection();
277 ~CriticalSection();
278
279 void Enter();
280 void Exit();
281
282 private:
283 CRITICAL_SECTION critical_section_;
284 uint32 number_entries_;
285
286 DISALLOW_EVIL_CONSTRUCTORS(CriticalSection);
287 };
288
289 // A class that manages a CriticalSection with its lifetime, you pass
290 // it one in the constructor and then it will either be freed in the
291 // destructor or implicitly [but only once]
292 class SingleLock {
293 public:
294 // TODO(omaha): Not sure if immediately locking is a good idea;
295 // the API is asymmetrical (there's an Unlock but no Lock).
296
297 // Lock a critical section immediately
298 explicit SingleLock(CriticalSection * cs);
299
300 // If we have not explicitly unlocked it, this destructor will
301 ~SingleLock();
302
303 // Release the lock explicitly [should be called only once, after that
304 // does nothing. If we do not do so, the destructor will]
305 HRESULT Unlock();
306
307 private:
308 CriticalSection * critical_section_;
309
310 DISALLOW_EVIL_CONSTRUCTORS(SingleLock);
311 };
312
313 // Encapsulation for kernel Event. Initializes and destroys with it's lifetime
314 class EventObj {
315 public:
316 explicit EventObj(const TCHAR * event_name) {
317 Init(event_name);
318 }
319 ~EventObj();
320 void Init(const TCHAR * event_name);
321 BOOL SetEvent();
322 HANDLE GetHandle() { return h_; }
323
324 private:
325 HANDLE h_;
326
327 DISALLOW_EVIL_CONSTRUCTORS(EventObj);
328 };
329
330 // Is the given handle signaled?
331 //
332 // Typically used for events.
333 bool IsHandleSignaled(HANDLE h);
334
335
336 enum SyncScope {
337 // local to a session
338 SYNC_LOCAL,
339
340 // global scope but the name is decorated to make it unique for the user
341 SYNC_USER,
342
343 // a globally scoped name
344 SYNC_GLOBAL,
345 };
346
347 // Create an id for the events/mutexes that can be used at the given scope
348 void CreateSyncId(const TCHAR* id, SyncScope scope, CString* sync_id);
349
350 // If any place needs to create a mutex that multiple
351 // processes need to access, use this.
352 HANDLE CreateMutexWithSyncAccess(const TCHAR* name,
353 LPSECURITY_ATTRIBUTES lock_attributes);
354
355 } // namespace omaha
356
357 #endif // OMAHA_BASE_SYNCHRONIZED_H_
358
OLDNEW
« no previous file with comments | « base/string_unittest.cc ('k') | base/synchronized.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698