summaryrefslogtreecommitdiff
path: root/cpp/src/IceUtil/StaticMutex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceUtil/StaticMutex.cpp')
-rw-r--r--cpp/src/IceUtil/StaticMutex.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/cpp/src/IceUtil/StaticMutex.cpp b/cpp/src/IceUtil/StaticMutex.cpp
new file mode 100644
index 00000000000..091aa5035f4
--- /dev/null
+++ b/cpp/src/IceUtil/StaticMutex.cpp
@@ -0,0 +1,79 @@
+// **********************************************************************
+//
+// Copyright (c) 2003
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+#include <IceUtil/StaticMutex.h>
+#include <IceUtil/ThreadException.h>
+
+#ifdef _WIN32
+# include <list>
+# include <algorithm>
+
+using namespace std;
+
+static CRITICAL_SECTION _criticalSection;
+static list<CRITICAL_SECTION*>* _criticalSectionList;
+
+// Although apparently not documented by Microsoft, static objects are
+// initialized before DllMain/DLL_PROCESS_ATTACH and finalized after
+// DllMain/DLL_PROCESS_DETACH ... that's why we use a static object.
+
+namespace IceUtil
+{
+
+class Init
+{
+public:
+
+ Init();
+ ~Init();
+};
+
+static Init _init;
+
+
+Init::Init()
+{
+ InitializeCriticalSection(&_criticalSection);
+ _criticalSectionList = new list<CRITICAL_SECTION*>;
+}
+
+Init::~Init()
+{
+ for_each(_criticalSectionList->begin(), _criticalSectionList->end(),
+ DeleteCriticalSection);
+ delete _criticalSectionList;
+ DeleteCriticalSection(&_criticalSection);
+}
+}
+
+// For full thread-safety, we assume that _mutexInitialized cannot be seen as true
+// before CRITICAL_SECTION has been updated. This is true on x86. Does IA64
+// provide the same memory ordering guarantees?
+//
+void IceUtil::StaticMutex::initialize() const
+{
+ EnterCriticalSection(&_criticalSection);
+ if(!_mutexInitialized)
+ {
+ InitializeCriticalSection(&_mutex);
+ _mutexInitialized = true;
+ _criticalSectionList->push_back(&_mutex);
+ }
+ LeaveCriticalSection(&_criticalSection);
+}
+
+#endif
+
+IceUtil::StaticMutex IceUtil::globalMutex = ICE_STATIC_MUTEX_INITIALIZER;
+