зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1219339: switch GetStaticInstance to use IPC's Singleton<T> impl r=froyd
This commit is contained in:
Родитель
e6486fd6be
Коммит
3a110e2974
|
@ -0,0 +1,35 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FakeIPC.h"
|
||||
#include <unistd.h>
|
||||
|
||||
// The implementations can't be in the .h file for some annoying reason
|
||||
|
||||
/* static */ void
|
||||
PlatformThread:: YieldCurrentThread()
|
||||
{
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
namespace base {
|
||||
|
||||
void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// see atomicops_internals_x86_gcc.h
|
||||
// This cheats to get the unittests to build
|
||||
|
||||
struct AtomicOps_x86CPUFeatureStruct {
|
||||
bool field1;
|
||||
bool field2;
|
||||
};
|
||||
|
||||
struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
|
||||
false,
|
||||
false,
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef FAKE_IPC_H_
|
||||
#define FAKE_IPC_H_
|
||||
#include <unistd.h>
|
||||
|
||||
class PlatformThread {
|
||||
public:
|
||||
static void YieldCurrentThread();
|
||||
};
|
||||
|
||||
namespace base {
|
||||
class AtExitManager {
|
||||
public:
|
||||
typedef void (*AtExitCallbackType)(void*);
|
||||
|
||||
static void RegisterCallback(AtExitCallbackType func, void* param);
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -32,6 +32,9 @@
|
|||
|
||||
#include "mtransport_test_utils.h"
|
||||
|
||||
#include "FakeIPC.h"
|
||||
#include "FakeIPC.cpp"
|
||||
|
||||
namespace mozilla {
|
||||
static std::string kAEqualsCandidate("a=candidate:");
|
||||
const static size_t kNumCandidatesPerComponent = 3;
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
#include "mtransport_test_utils.h"
|
||||
|
||||
#include "FakeIPC.h"
|
||||
#include "FakeIPC.cpp"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class JsepTrackTest : public ::testing::Test
|
||||
|
|
|
@ -22,6 +22,9 @@ using namespace std;
|
|||
#include "runnable_utils.h"
|
||||
#include "signaling/src/common/EncodingConstraints.h"
|
||||
|
||||
#include "FakeIPC.h"
|
||||
#include "FakeIPC.cpp"
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest_utils.h"
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
|
||||
#include "webrtc/modules/interface/module_common_types.h"
|
||||
|
||||
#include "FakeIPC.h"
|
||||
#include "FakeIPC.cpp"
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest_utils.h"
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
#include "signaling/src/sdp/SipccSdpParser.h"
|
||||
|
||||
#include "FakeIPC.h"
|
||||
#include "FakeIPC.cpp"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
const std::string kDefaultFilename((char *)"/tmp/sdp.bin");
|
||||
|
|
|
@ -44,6 +44,9 @@ extern "C" {
|
|||
#endif
|
||||
#define CRLF "\r\n"
|
||||
|
||||
#include "FakeIPC.h"
|
||||
#include "FakeIPC.cpp"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
namespace test {
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
#include "PeerConnectionImplEnumsBinding.cpp"
|
||||
#endif
|
||||
|
||||
#include "FakeIPC.h"
|
||||
#include "FakeIPC.cpp"
|
||||
|
||||
#include "ice_ctx.h"
|
||||
#include "ice_peer_ctx.h"
|
||||
|
||||
|
|
|
@ -29,10 +29,10 @@ public:
|
|||
int32_t RegisterSSRC(const uint32_t ssrc);
|
||||
int32_t ReturnSSRC(const uint32_t ssrc);
|
||||
|
||||
protected:
|
||||
SSRCDatabase();
|
||||
virtual ~SSRCDatabase();
|
||||
|
||||
protected:
|
||||
static SSRCDatabase* CreateInstance() { return new SSRCDatabase(); }
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
#ifdef _WIN32
|
||||
#include "webrtc/system_wrappers/interface/fix_interlocked_exchange_pointer_win.h"
|
||||
#if defined(WEBRTC_ANDROID) || defined(WEBRTC_GONK)
|
||||
#define OS_LINUX
|
||||
#endif
|
||||
#include "base/singleton.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
|
@ -35,119 +35,9 @@ 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;
|
||||
// Simple solution since we don't use this for large objects anymore
|
||||
return Singleton<T>::get();
|
||||
}
|
||||
|
||||
} // namspace webrtc
|
||||
|
||||
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATIC_INSTANCE_H_
|
||||
|
|
|
@ -69,7 +69,11 @@ bool RWLockWin::LoadModule() {
|
|||
if (!library) {
|
||||
return false;
|
||||
}
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Kernel.dll");
|
||||
// Don't log here, since we may be creating a FileWrapper for
|
||||
// the TraceImpl, from within GetStaticInstance. With singleton.h, you
|
||||
// can't safely call GetStaticInstance on the same object from within
|
||||
// creating that object (go figure...)
|
||||
//WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Kernel.dll");
|
||||
|
||||
initialize_srw_lock =
|
||||
(InitializeSRWLock)GetProcAddress(library, "InitializeSRWLock");
|
||||
|
@ -88,7 +92,7 @@ bool RWLockWin::LoadModule() {
|
|||
if (initialize_srw_lock && acquire_srw_lock_exclusive &&
|
||||
release_srw_lock_exclusive && acquire_srw_lock_shared &&
|
||||
release_srw_lock_shared) {
|
||||
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Native RW Lock");
|
||||
//WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Loaded Native RW Lock");
|
||||
native_rw_locks_supported = true;
|
||||
}
|
||||
return native_rw_locks_supported;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "base/singleton.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "webrtc/system_wrappers/source/trace_win.h"
|
||||
|
@ -63,7 +64,12 @@ TraceImpl* TraceImpl::StaticInstance(CountOperation count_operation,
|
|||
}
|
||||
}
|
||||
TraceImpl* impl =
|
||||
GetStaticInstance<TraceImpl>(count_operation);
|
||||
#if defined(_WIN32)
|
||||
GetStaticInstance<TraceWindows>(count_operation);
|
||||
#else
|
||||
GetStaticInstance<TracePosix>(count_operation);
|
||||
#endif
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче