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

Side by Side Diff: webrtc/system_wrappers/include/static_instance.h

Issue 2779623002: remove more CriticalSectionWrappers. (Closed)
Patch Set: Add override Created 3 years, 8 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #ifndef WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_ 11 #ifndef WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_
12 #define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_ 12 #define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_
13 13
14 #include <assert.h> 14 #include <assert.h>
15 15
16 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 16 #include "webrtc/base/criticalsection.h"
17 #ifdef _WIN32 17 #ifdef _WIN32
18 #include "webrtc/system_wrappers/include/fix_interlocked_exchange_pointer_win.h" 18 #include "webrtc/system_wrappers/include/fix_interlocked_exchange_pointer_win.h"
19 #endif 19 #endif
20 20
21 namespace webrtc { 21 namespace webrtc {
22 22
23 enum CountOperation { 23 enum CountOperation {
24 kRelease, 24 kRelease,
25 kAddRef, 25 kAddRef,
26 kAddRefNoCreate 26 kAddRefNoCreate
27 }; 27 };
28 enum CreateOperation { 28 enum CreateOperation {
29 kInstanceExists, 29 kInstanceExists,
30 kCreate, 30 kCreate,
31 kDestroy 31 kDestroy
32 }; 32 };
33 33
34 template <class T> 34 template <class T>
35 // Construct On First Use idiom. Avoids 35 // Construct On First Use idiom. Avoids
36 // "static initialization order fiasco". 36 // "static initialization order fiasco".
37 static T* GetStaticInstance(CountOperation count_operation) { 37 static T* GetStaticInstance(CountOperation count_operation) {
38 // TODO (hellner): use atomic wrapper instead. 38 // TODO (hellner): use atomic wrapper instead.
39 static volatile long instance_count = 0; 39 static volatile long instance_count = 0;
40 static T* volatile instance = NULL; 40 static T* volatile instance = NULL;
41 CreateOperation state = kInstanceExists; 41 CreateOperation state = kInstanceExists;
42 #ifndef _WIN32 42 #ifndef _WIN32
43 // This memory is staticly allocated once. The application does not try to 43 rtc::CriticalSection crit_sect;
44 // free this memory. This approach is taken to avoid issues with 44 rtc::CritScope lock(&crit_sect);
45 // destruction order for statically allocated memory. The memory will be
46 // reclaimed by the OS and memory leak tools will not recognize memory
47 // reachable from statics leaked so no noise is added by doing this.
48 static CriticalSectionWrapper* crit_sect(
49 CriticalSectionWrapper::CreateCriticalSection());
50 CriticalSectionScoped lock(crit_sect);
51 45
52 if (count_operation == 46 if (count_operation ==
53 kAddRefNoCreate && instance_count == 0) { 47 kAddRefNoCreate && instance_count == 0) {
54 return NULL; 48 return NULL;
55 } 49 }
56 if (count_operation == 50 if (count_operation ==
57 kAddRef || 51 kAddRef ||
58 count_operation == kAddRefNoCreate) { 52 count_operation == kAddRefNoCreate) {
59 instance_count++; 53 instance_count++;
60 if (instance_count == 1) { 54 if (instance_count == 1) {
61 state = kCreate; 55 state = kCreate;
62 } 56 }
63 } else { 57 } else {
64 instance_count--; 58 instance_count--;
65 if (instance_count == 0) { 59 if (instance_count == 0) {
66 state = kDestroy; 60 state = kDestroy;
67 } 61 }
68 } 62 }
69 if (state == kCreate) { 63 if (state == kCreate) {
70 instance = T::CreateInstance(); 64 instance = T::CreateInstance();
71 } else if (state == kDestroy) { 65 } else if (state == kDestroy) {
72 T* old_instance = instance; 66 T* old_instance = instance;
73 instance = NULL; 67 instance = NULL;
74 // The state will not change past this point. Release the critical 68 // The state will not change past this point. Release the critical
75 // section while deleting the object in case it would be blocking on 69 // section while deleting the object in case it would be blocking on
76 // access back to this object. (This is the case for the tracing class 70 // access back to this object. (This is the case for the tracing class
77 // since the thread owned by the tracing class also traces). 71 // since the thread owned by the tracing class also traces).
78 // TODO(hellner): this is a bit out of place but here goes, de-couple 72 // TODO(hellner): this is a bit out of place but here goes, de-couple
79 // thread implementation with trace implementation. 73 // thread implementation with trace implementation.
80 crit_sect->Leave(); 74 crit_sect.Leave();
81 if (old_instance) { 75 if (old_instance) {
82 delete old_instance; 76 delete old_instance;
83 } 77 }
84 // Re-acquire the lock since the scoped critical section will release 78 // Re-acquire the lock since the scoped critical section will release
85 // it. 79 // it.
86 crit_sect->Enter(); 80 crit_sect.Enter();
87 return NULL; 81 return NULL;
88 } 82 }
89 #else // _WIN32 83 #else // _WIN32
90 if (count_operation == 84 if (count_operation ==
91 kAddRefNoCreate && instance_count == 0) { 85 kAddRefNoCreate && instance_count == 0) {
92 return NULL; 86 return NULL;
93 } 87 }
94 if (count_operation == kAddRefNoCreate) { 88 if (count_operation == kAddRefNoCreate) {
95 if (1 == InterlockedIncrement(&instance_count)) { 89 if (1 == InterlockedIncrement(&instance_count)) {
96 // The instance has been destroyed by some other thread. Rollback. 90 // The instance has been destroyed by some other thread. Rollback.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 } 138 }
145 return NULL; 139 return NULL;
146 } 140 }
147 #endif // #ifndef _WIN32 141 #endif // #ifndef _WIN32
148 return instance; 142 return instance;
149 } 143 }
150 144
151 } // namspace webrtc 145 } // namspace webrtc
152 146
153 #endif // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_ 147 #endif // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698