summaryrefslogtreecommitdiffhomepage
path: root/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp')
-rw-r--r--ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp
new file mode 100644
index 0000000..550d6f4
--- /dev/null
+++ b/ovr_sdk_win_23.0.0/LibOVRKernel/Src/Kernel/OVR_System.cpp
@@ -0,0 +1,214 @@
+/************************************************************************************
+
+Filename : OVR_System.cpp
+Content : General kernel initialization/cleanup, including that
+ of the memory allocator.
+Created : September 19, 2012
+Notes :
+
+Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
+
+Licensed under the Oculus Master SDK License Version 1.0 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+https://developer.oculus.com/licenses/oculusmastersdk-1.0
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+#include "OVR_System.h"
+#include <new>
+#include "Logging/Logging_Library.h"
+#include "OVR_DebugHelp.h"
+#include "OVR_Threads.h"
+#include "OVR_Timer.h"
+
+#if defined(_MSC_VER)
+#include <new.h>
+#else
+#include <new>
+#endif
+
+#ifdef OVR_OS_MS
+#pragma warning(push, 0)
+#include "OVR_Win32_IncludeWindows.h" // GetModuleHandleEx
+#pragma warning(pop)
+#endif
+
+static ovrlog::Channel Logger("Kernel:System");
+
+namespace OVR {
+
+//-----------------------------------------------------------------------------
+// Initialization/Shutdown state
+// If true, then Destroy() was called and is in the process of executing
+// Added to fix race condition if thread is started after the call to System::Destroy()
+static bool ShuttingDown = false;
+
+//-----------------------------------------------------------------------------
+// Initialization/Shutdown Callbacks
+
+static SystemSingletonInternal* SystemShutdownListenerList =
+ nullptr; // Points to the most recent SystemSingletonInternal added to the list.
+
+static Lock& GetSSILock() { // Put listLock in a function so that it can be constructed on-demand.
+ static Lock listLock; // Will construct on the first usage. However, the guarding of this
+ // construction is not thread-safe
+ return listLock; // under all compilers. However, since we are initially calling this on startup
+ // before other threads
+} // could possibly exist, the first usage of this will be before other threads exist.
+
+void SystemSingletonInternal::RegisterDestroyCallback() {
+ GetSSILock().DoLock();
+ if (ShuttingDown) {
+ GetSSILock().Unlock();
+
+ OnThreadDestroy();
+ } else {
+ GetSSILock().Unlock();
+
+ // Insert the listener at the front of the list (top of the stack). This is an analogue of a C++
+ // forward_list::push_front or stack::push.
+ NextShutdownSingleton = SystemShutdownListenerList;
+ SystemShutdownListenerList = this;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// System
+
+static int System_Init_Count = 0;
+
+#if defined(_MSC_VER)
+// This allows us to throw OVR::bad_alloc instead of std::bad_alloc, which provides less
+// information.
+int OVRNewFailureHandler(size_t /*size*/) {
+ throw OVR::bad_alloc();
+
+ // Disabled because otherwise a compiler warning is generated regarding unreachable code.
+ // return 0; // A return value of 0 tells the Standard Library to not retry the allocation.
+}
+#else
+// This allows us to throw OVR::bad_alloc instead of std::bad_alloc, which provides less
+// information.
+void OVRNewFailureHandler() {
+ throw OVR::bad_alloc();
+}
+#endif
+
+// Initializes System core, installing allocator.
+void System::Init() {
+ // Restart logging if we shut down before
+ ovrlog::RestartLogging();
+
+#if defined(_MSC_VER)
+ // Make it so that failure of the C malloc family of functions results in the same behavior as C++
+ // operator new failure.
+ // This allows us to throw exceptions for malloc usage the same as for operator new bad_alloc.
+ _set_new_mode(1);
+
+ // Tells the standard library to direct new (and malloc) failures to us. Normally we wouldn't need
+ // to do this, as the
+ // C++ Standard Library already throws std::bad_alloc on operator new failure. The problem is that
+ // the Standard Library doesn't
+ // throw std::bad_alloc upon malloc failure, and we can only intercept malloc failure via this
+ // means. _set_new_handler specifies
+ // a global handler for the current running Standard Library. If the Standard Library is being
+ // dynamically linked instead
+ // of statically linked, then this is a problem because a call to _set_new_handler would override
+ // anything the application
+ // has already set.
+ _set_new_handler(OVRNewFailureHandler);
+#else
+ // This allows us to throw OVR::bad_alloc instead of std::bad_alloc, which provides less
+ // information.
+ // Question: Does this set the handler for all threads or just the current thread? The C++
+ // Standard doesn't
+ // explicitly state this, though it may be implied from other parts of the Standard.
+ std::set_new_handler(OVRNewFailureHandler);
+#endif
+
+ if (++System_Init_Count == 1) {
+ Timer::initializeTimerSystem();
+ } else {
+ Logger.LogError("Init recursively called; depth = ", System_Init_Count);
+ // XXX Should this just exit?
+ }
+}
+
+void System::Stop() {
+ GetSSILock().DoLock();
+ ShuttingDown = true;
+ GetSSILock().Unlock();
+
+ if (--System_Init_Count == 0) {
+ Logger.LogInfo("Graceful shutdown: OnThreadDestroy");
+
+ // Invoke all of the post-finish callbacks (normal case)
+ for (SystemSingletonInternal* listener = SystemShutdownListenerList; listener;
+ listener = listener->NextShutdownSingleton) {
+ listener->OnThreadDestroy();
+ }
+ } else {
+ Logger.LogError("Stop recursively called; depth = ", System_Init_Count);
+ }
+}
+
+void System::Destroy() {
+ if (!ShuttingDown) {
+ Logger.LogWarning("Destroy called before Stop");
+ System::Stop();
+ }
+
+ if (System_Init_Count == 0) {
+ Logger.LogInfo("Graceful shutdown: OnSystemDestroy");
+
+ // Invoke all of the post-finish callbacks (normal case)
+ for (SystemSingletonInternal *next, *listener = SystemShutdownListenerList; listener;
+ listener = next) {
+ next = listener->NextShutdownSingleton;
+ listener->OnSystemDestroy();
+ }
+
+ SystemShutdownListenerList = nullptr;
+
+ Timer::shutdownTimerSystem();
+ } else {
+ Logger.LogError("Destroy recursively called; depth = ", System_Init_Count);
+ }
+
+ GetSSILock().DoLock();
+ ShuttingDown = false;
+ GetSSILock().Unlock();
+
+ Logger.LogInfo("Graceful shutdown: Stopping logger");
+
+ // Prevent memory leak reports
+ ovrlog::ShutdownLogging();
+}
+
+// Returns 'true' if system was properly initialized.
+bool System::IsInitialized() {
+ return System_Init_Count > 0;
+}
+
+// Dump any leaked memory
+void System::CheckForAllocatorLeaks() {
+ if (Allocator::IsTrackingLeaks()) {
+ int ovrLeakCount = Allocator::DumpMemory();
+ (void)ovrLeakCount;
+
+ OVR_ASSERT(ovrLeakCount == 0);
+ }
+}
+
+} // namespace OVR