diff options
Diffstat (limited to 'webrtc/system_wrappers/include/static_instance.h')
-rw-r--r-- | webrtc/system_wrappers/include/static_instance.h | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/webrtc/system_wrappers/include/static_instance.h b/webrtc/system_wrappers/include/static_instance.h deleted file mode 100644 index 41946d9..0000000 --- a/webrtc/system_wrappers/include/static_instance.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_ -#define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_ - -#include <assert.h> - -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#ifdef _WIN32 -#include "webrtc/system_wrappers/include/fix_interlocked_exchange_pointer_win.h" -#endif - -namespace webrtc { - -enum CountOperation { - kRelease, - kAddRef, - kAddRefNoCreate -}; -enum CreateOperation { - kInstanceExists, - kCreate, - kDestroy -}; - -template <class T> -// Construct On First Use idiom. Avoids -// "static initialization order fiasco". -static T* GetStaticInstance(CountOperation count_operation) { - // TODO (hellner): use atomic wrapper instead. - static volatile long instance_count = 0; - static T* volatile instance = NULL; - CreateOperation state = kInstanceExists; -#ifndef _WIN32 - // This memory is staticly allocated once. The application does not try to - // free this memory. This approach is taken to avoid issues with - // destruction order for statically allocated memory. The memory will be - // reclaimed by the OS and memory leak tools will not recognize memory - // reachable from statics leaked so no noise is added by doing this. - static CriticalSectionWrapper* crit_sect( - CriticalSectionWrapper::CreateCriticalSection()); - CriticalSectionScoped lock(crit_sect); - - if (count_operation == - kAddRefNoCreate && instance_count == 0) { - return NULL; - } - if (count_operation == - kAddRef || - count_operation == kAddRefNoCreate) { - instance_count++; - if (instance_count == 1) { - state = kCreate; - } - } else { - instance_count--; - if (instance_count == 0) { - state = kDestroy; - } - } - if (state == kCreate) { - instance = T::CreateInstance(); - } else if (state == kDestroy) { - T* old_instance = instance; - instance = NULL; - // The state will not change past this point. Release the critical - // section while deleting the object in case it would be blocking on - // access back to this object. (This is the case for the tracing class - // since the thread owned by the tracing class also traces). - // TODO(hellner): this is a bit out of place but here goes, de-couple - // thread implementation with trace implementation. - crit_sect->Leave(); - if (old_instance) { - delete old_instance; - } - // Re-acquire the lock since the scoped critical section will release - // it. - crit_sect->Enter(); - return NULL; - } -#else // _WIN32 - if (count_operation == - kAddRefNoCreate && instance_count == 0) { - return NULL; - } - if (count_operation == kAddRefNoCreate) { - if (1 == InterlockedIncrement(&instance_count)) { - // The instance has been destroyed by some other thread. Rollback. - InterlockedDecrement(&instance_count); - assert(false); - return NULL; - } - // Sanity to catch corrupt state. - if (instance == NULL) { - assert(false); - InterlockedDecrement(&instance_count); - return NULL; - } - } else if (count_operation == kAddRef) { - if (instance_count == 0) { - state = kCreate; - } else { - if (1 == InterlockedIncrement(&instance_count)) { - // InterlockedDecrement because reference count should not be - // updated just yet (that's done when the instance is created). - InterlockedDecrement(&instance_count); - state = kCreate; - } - } - } else { - int new_value = InterlockedDecrement(&instance_count); - if (new_value == 0) { - state = kDestroy; - } - } - - if (state == kCreate) { - // Create instance and let whichever thread finishes first assign its - // local copy to the global instance. All other threads reclaim their - // local copy. - T* new_instance = T::CreateInstance(); - if (1 == InterlockedIncrement(&instance_count)) { - InterlockedExchangePointer(reinterpret_cast<void * volatile*>(&instance), - new_instance); - } else { - InterlockedDecrement(&instance_count); - if (new_instance) { - delete static_cast<T*>(new_instance); - } - } - } else if (state == kDestroy) { - T* old_value = static_cast<T*>(InterlockedExchangePointer( - reinterpret_cast<void * volatile*>(&instance), NULL)); - if (old_value) { - delete static_cast<T*>(old_value); - } - return NULL; - } -#endif // #ifndef _WIN32 - return instance; -} - -} // namspace webrtc - -#endif // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_STATIC_INSTANCE_H_ |