diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Freeze/Application.cpp | 1 | ||||
-rw-r--r-- | cpp/src/Ice/Application.cpp | 303 | ||||
-rw-r--r-- | cpp/src/Ice/CommunicatorI.cpp | 19 | ||||
-rw-r--r-- | cpp/src/Ice/CommunicatorI.h | 11 | ||||
-rw-r--r-- | cpp/src/Ice/ThreadPool.h | 2 | ||||
-rw-r--r-- | cpp/src/IceUtil/.depend | 4 | ||||
-rw-r--r-- | cpp/src/IceUtil/CtrlCHandler.cpp | 208 | ||||
-rw-r--r-- | cpp/src/IceUtil/Makefile | 2 | ||||
-rw-r--r-- | cpp/src/IceUtil/StaticMutex.cpp | 79 | ||||
-rw-r--r-- | cpp/src/IceUtil/iceutil.dsp | 16 |
10 files changed, 466 insertions, 179 deletions
diff --git a/cpp/src/Freeze/Application.cpp b/cpp/src/Freeze/Application.cpp index 9b40cb5f3c4..ecd80f0e3b2 100644 --- a/cpp/src/Freeze/Application.cpp +++ b/cpp/src/Freeze/Application.cpp @@ -81,6 +81,5 @@ Freeze::Application::run(int argc, char* argv[]) dbEnv = 0; } - defaultInterrupt(); return status; } diff --git a/cpp/src/Ice/Application.cpp b/cpp/src/Ice/Application.cpp index 943514b6f16..b0d0268ceb8 100644 --- a/cpp/src/Ice/Application.cpp +++ b/cpp/src/Ice/Application.cpp @@ -13,33 +13,102 @@ // ********************************************************************** #include <Ice/Application.h> - -#ifndef _WIN32 -#include <signal.h> -#endif +#include <IceUtil/StaticMutex.h> +#include <IceUtil/CtrlCHandler.h> +#include <IceUtil/Cond.h> +#include <memory> using namespace std; using namespace Ice; +using namespace IceUtil; -const char* Application::_appName = 0; -CommunicatorPtr Application::_communicator; +static const char* _appName = 0; +static CommunicatorPtr _communicator; -bool Application::_interrupted = false; +static bool _interrupted = false; +static StaticMutex _mutex = ICE_STATIC_MUTEX_INITIALIZER; -#ifndef _WIN32 -const int Application::signals[] = { SIGHUP, SIGINT, SIGTERM }; -sigset_t Application::signalSet; +static bool _released = false; +static auto_ptr<Cond> _condVar; +static auto_ptr<IceUtil::CtrlCHandler> _ctrlCHandler; +static IceUtil::CtrlCHandlerCallback _previousCallback = 0; +static bool _nohup = false; + +#ifdef _WIN32 +const DWORD SIGHUP = CTRL_LOGOFF_EVENT; +#else +# include <csignal> #endif -Ice::Application::Application() + +// CtrlCHandler callbacks +// + +static void holdInterruptCallback(int signal) { -#ifndef _WIN32 - sigemptyset(&signalSet); - for (unsigned i = 0; i < sizeof(signals) / sizeof(*signals); ++i) { - sigaddset(&signalSet, signals[i]); + StaticMutex::Lock lock(_mutex); + while(!_released) + { + _condVar->wait(lock); + } } -#endif + + // Use the current callback to process this (old) signal + // + CtrlCHandlerCallback callback = _ctrlCHandler->getCallback(); + if(callback != 0) + { + callback(signal); + } +} + +static void shutdownOnInterruptCallback(int signal) +{ + if(_nohup && signal == SIGHUP) + { + return; + } + + { + StaticMutex::Lock lock(_mutex); + _interrupted = true; + } + + try + { + _communicator->shutdown(); + } + catch(const IceUtil::Exception& ex) + { + cerr << _appName << " (while shutting down in response to signal " << signal + << "): " << ex << endl; + } + catch(const std::exception& ex) + { + cerr << _appName << " (while shutting down in response to signal " << signal + << "): std::exception: " << ex.what() << endl; + } + catch(const std::string& msg) + { + cerr << _appName << " (while shutting down in response to signal " << signal + << "): " << msg << endl; + } + catch(const char * msg) + { + cerr << _appName << " (while shutting down in response to signal " << signal + << "): " << msg << endl; + } + catch(...) + { + cerr << _appName << " (while shutting down in response to signal " << signal + << "): unknown exception" << endl; + } +} + + +Ice::Application::Application() +{ } Ice::Application::~Application() @@ -55,8 +124,17 @@ Ice::Application::main(int argc, char* argv[], const char* configFile) return EXIT_FAILURE; } - Application::_interrupted = false; + _interrupted = false; _appName = argv[0]; + if(_condVar.get() == 0) + { + _condVar.reset(new Cond); + } + + + // Ignore signals for a little while + // + _ctrlCHandler.reset(new IceUtil::CtrlCHandler); int status; @@ -72,6 +150,15 @@ Ice::Application::main(int argc, char* argv[], const char* configFile) { _communicator = initialize(argc, argv); } + + // Used by shutdownOnInterruptCallback + // + _nohup = (_communicator->getProperties()->getPropertyAsInt("Ice.Nohup") > 0); + + // The default is to shutdown when a signal is received: + // + shutdownOnInterrupt(); + status = run(argc, argv); } catch(const Exception& ex) @@ -102,6 +189,11 @@ Ice::Application::main(int argc, char* argv[], const char* configFile) if(_communicator) { + // We don't want to handle signals anymore + // + ignoreInterrupt(); // will release any signal still held + _ctrlCHandler.reset(); + try { _communicator->destroy(); @@ -149,164 +241,83 @@ Ice::Application::communicator() return _communicator; } -#ifdef _WIN32 - -BOOL WINAPI -Ice::interruptHandler(DWORD) -{ - Application::_interrupted = true; - - // - // Don't use Application::communicator(), this is not signal-safe. - // - assert(Application::_communicator); - Application::_communicator->signalShutdown(); - return TRUE; -} - -enum InterruptDisposition { Shutdown, Ignore, Default }; -static InterruptDisposition currentDisposition = Default; - void Ice::Application::shutdownOnInterrupt() { - SetConsoleCtrlHandler(NULL, FALSE); - SetConsoleCtrlHandler(interruptHandler, TRUE); - currentDisposition = Shutdown; -} - -void -Ice::Application::ignoreInterrupt() -{ - SetConsoleCtrlHandler(interruptHandler, FALSE); - SetConsoleCtrlHandler(NULL, TRUE); - currentDisposition = Ignore; -} - -void -Ice::Application::defaultInterrupt() -{ - SetConsoleCtrlHandler(interruptHandler, FALSE); - SetConsoleCtrlHandler(NULL, FALSE); - currentDisposition = Default; -} - -void -Ice::Application::holdInterrupt() -{ - // - // With Windows, we can't block signals and - // remember them the way we can with UNIX, - // so "holding" an interrupt is the same as - // ignoring it. - // - SetConsoleCtrlHandler(interruptHandler, FALSE); - SetConsoleCtrlHandler(NULL, TRUE); -} - -void -Ice::Application::releaseInterrupt() -{ - // - // Restore current signal disposition. - // - switch(currentDisposition) + assert(_ctrlCHandler.get() != 0); + + StaticMutex::Lock lock(_mutex); + if(_ctrlCHandler->getCallback() == holdInterruptCallback) { - case Shutdown: - { - shutdownOnInterrupt(); - break; - } - case Ignore: - { - ignoreInterrupt(); - break; - } - case Default: - { - defaultInterrupt(); - break; - } - default: - { - assert(false); - break; - } + _released = true; + _ctrlCHandler->setCallback(shutdownOnInterruptCallback); + lock.release(); + _condVar->signal(); } -} - -#else - -void -Ice::interruptHandler(int) -{ - Application::_interrupted = true; - - // - // Don't use Application::communicator(), this is not signal-safe. - // - assert(Application::_communicator); - Application::_communicator->signalShutdown(); -} - -void -Ice::Application::shutdownOnInterrupt() -{ - struct sigaction action; - memset(&action, 0, sizeof(action)); - action.sa_handler = interruptHandler; - action.sa_mask = signalSet; - action.sa_flags = SA_RESTART; - for (unsigned i = 0; i < sizeof(signals) / sizeof(*signals); ++i) + else { - sigaction(signals[i], &action, 0); + _ctrlCHandler->setCallback(shutdownOnInterruptCallback); } } void Ice::Application::ignoreInterrupt() { - struct sigaction action; - memset(&action, 0, sizeof(action)); - action.sa_handler = SIG_IGN; - action.sa_mask = signalSet; - action.sa_flags = SA_RESTART; - for (unsigned i = 0; i < sizeof(signals) / sizeof(*signals); ++i) + assert(_ctrlCHandler.get() != 0); + + StaticMutex::Lock lock(_mutex); + if(_ctrlCHandler->getCallback() == holdInterruptCallback) { - sigaction(signals[i], &action, 0); + _released = true; + _ctrlCHandler->setCallback(0); + lock.release(); + _condVar->signal(); } -} - -void -Ice::Application::defaultInterrupt() -{ - struct sigaction action; - memset(&action, 0, sizeof(action)); - action.sa_handler = SIG_DFL; - action.sa_mask = signalSet; - action.sa_flags = SA_RESTART; - for (unsigned i = 0; i < sizeof(signals) / sizeof(*signals); ++i) + else { - sigaction(signals[i], &action, 0); + _ctrlCHandler->setCallback(0); } } void Ice::Application::holdInterrupt() { - sigprocmask(SIG_BLOCK, &signalSet, 0); + assert(_ctrlCHandler.get() != 0); + + StaticMutex::Lock lock(_mutex); + if(_ctrlCHandler->getCallback() != holdInterruptCallback) + { + _previousCallback = _ctrlCHandler->getCallback(); + _released = false; + _ctrlCHandler->setCallback(holdInterruptCallback); + } + // else, we were already holding signals } void Ice::Application::releaseInterrupt() { - sigprocmask(SIG_UNBLOCK, &signalSet, 0); -} + assert(_ctrlCHandler.get() != 0); -#endif + StaticMutex::Lock lock(_mutex); + if(_ctrlCHandler->getCallback() == holdInterruptCallback) + { + // Note that it's very possible no signal is held; + // in this case the callback is just replaced and + // setting _released to true and signalling _condVar + // do no harm. + + _released = true; + _ctrlCHandler->setCallback(_previousCallback); + lock.release(); + _condVar->signal(); + } + // else nothing to release +} bool Ice::Application::interrupted() { - return Application::_interrupted; + StaticMutex::Lock lock(_mutex); + return _interrupted; } diff --git a/cpp/src/Ice/CommunicatorI.cpp b/cpp/src/Ice/CommunicatorI.cpp index e9a2ad4fcc6..f0272f655ca 100644 --- a/cpp/src/Ice/CommunicatorI.cpp +++ b/cpp/src/Ice/CommunicatorI.cpp @@ -17,7 +17,6 @@ #include <Ice/Properties.h> #include <Ice/ReferenceFactory.h> #include <Ice/ProxyFactory.h> -#include <Ice/ThreadPool.h> #include <Ice/ObjectFactoryManager.h> #include <Ice/UserExceptionFactoryManager.h> #include <Ice/ObjectAdapterFactory.h> @@ -40,7 +39,6 @@ Ice::CommunicatorI::destroy() if(!_destroyed) // Don't destroy twice. { _destroyed = true; - _serverThreadPool = 0; instance = _instance; } } @@ -74,18 +72,6 @@ Ice::CommunicatorI::shutdown() } void -Ice::CommunicatorI::signalShutdown() -{ - // - // No mutex locking here! This operation must be signal-safe. - // - if(_serverThreadPool) - { - _serverThreadPool->initiateShutdown(); - } -} - -void Ice::CommunicatorI::waitForShutdown() { ObjectAdapterFactoryPtr objectAdapterFactory; @@ -140,11 +126,6 @@ Ice::CommunicatorI::createObjectAdapter(const string& name) ObjectAdapterPtr adapter = _instance->objectAdapterFactory()->createObjectAdapter(name); - if(!_serverThreadPool) // Lazy initialization of _serverThreadPool. - { - _serverThreadPool = _instance->serverThreadPool(); - } - return adapter; } diff --git a/cpp/src/Ice/CommunicatorI.h b/cpp/src/Ice/CommunicatorI.h index d4b7d89a013..6b6f35bfa55 100644 --- a/cpp/src/Ice/CommunicatorI.h +++ b/cpp/src/Ice/CommunicatorI.h @@ -17,7 +17,6 @@ #include <IceUtil/RecMutex.h> -#include <Ice/ThreadPoolF.h> #include <Ice/DynamicLibraryF.h> #include <Ice/Initialize.h> #include <Ice/Communicator.h> @@ -31,7 +30,6 @@ public: virtual void destroy(); virtual void shutdown(); - virtual void signalShutdown(); virtual void waitForShutdown(); virtual ObjectPrx stringToProxy(const std::string&); @@ -81,15 +79,6 @@ private: ::IceInternal::InstancePtr _instance; // - // We need _serverThreadPool directly in CommunicatorI. That's - // because the shutdown() operation is signal-safe, and thus must - // not access any mutex locks or _instance. It may only access - // _serverThreadPool->initiateShutdown(), which is signal-safe as - // well. - // - ::IceInternal::ThreadPoolPtr _serverThreadPool; - - // // We don't want the dynamic libraries to be unloaded until the // Communicator's destructor is invoked. // diff --git a/cpp/src/Ice/ThreadPool.h b/cpp/src/Ice/ThreadPool.h index 885a7f33008..1f514c6535f 100644 --- a/cpp/src/Ice/ThreadPool.h +++ b/cpp/src/Ice/ThreadPool.h @@ -48,11 +48,11 @@ public: void _register(SOCKET, const EventHandlerPtr&); void unregister(SOCKET); void promoteFollower(); - void initiateShutdown(); // Signal-safe shutdown initiation. void joinWithAllThreads(); private: + void initiateShutdown(); // Signal-safe shutdown initiation. bool clearInterrupt(); void setInterrupt(char); diff --git a/cpp/src/IceUtil/.depend b/cpp/src/IceUtil/.depend index b29e659154e..be0e6e52ae6 100644 --- a/cpp/src/IceUtil/.depend +++ b/cpp/src/IceUtil/.depend @@ -1,11 +1,13 @@ Exception.o: Exception.cpp ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h Unicode.o: Unicode.cpp ../../include/IceUtil/Unicode.h ../../include/IceUtil/Config.h -UUID.o: UUID.cpp ../../include/IceUtil/UUID.h ../../include/IceUtil/Config.h ../../include/IceUtil/Unicode.h +UUID.o: UUID.cpp ../../include/IceUtil/UUID.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Unicode.h RecMutex.o: RecMutex.cpp ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h RWRecMutex.o: RWRecMutex.cpp ../../include/IceUtil/RWRecMutex.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h Cond.o: Cond.cpp ../../include/IceUtil/Cond.h ../../include/IceUtil/Config.h ../../include/IceUtil/Time.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h Thread.o: Thread.cpp ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Time.h ThreadException.o: ThreadException.cpp ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h +StaticMutex.o: StaticMutex.cpp ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h +CtrlCHandler.o: CtrlCHandler.cpp ../../include/IceUtil/CtrlCHandler.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h Time.o: Time.cpp ../../include/IceUtil/Time.h ../../include/IceUtil/Config.h InputUtil.o: InputUtil.cpp ../../include/IceUtil/InputUtil.h ../../include/IceUtil/Config.h OutputUtil.o: OutputUtil.cpp ../../include/IceUtil/OutputUtil.h ../../include/IceUtil/Config.h diff --git a/cpp/src/IceUtil/CtrlCHandler.cpp b/cpp/src/IceUtil/CtrlCHandler.cpp new file mode 100644 index 00000000000..9c7c53220dc --- /dev/null +++ b/cpp/src/IceUtil/CtrlCHandler.cpp @@ -0,0 +1,208 @@ +// ********************************************************************** +// +// 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/CtrlCHandler.h> +#include <IceUtil/StaticMutex.h> + +#ifndef _WIN32 +# ifdef __sun +# define _POSIX_PTHREAD_SEMANTICS +# endif +# include <signal.h> +#endif + +using namespace std; +using namespace IceUtil; + +static CtrlCHandlerCallback _callback = 0; +static const CtrlCHandler* _handler = 0; + +CtrlCHandlerException::CtrlCHandlerException(const char* file, int line) : + Exception(file, line) +{ +} + +string +CtrlCHandlerException::ice_name() const +{ + return "IceUtil::CtrlCHandlerException"; +} + +Exception* +CtrlCHandlerException::ice_clone() const +{ + return new CtrlCHandlerException(*this); +} + +void +CtrlCHandlerException::ice_throw() const +{ + throw *this; +} + +void +CtrlCHandler::setCallback(CtrlCHandlerCallback callback) +{ + StaticMutex::Lock lock(globalMutex); + _callback = callback; +} + +CtrlCHandlerCallback +CtrlCHandler::getCallback() const +{ + StaticMutex::Lock lock(globalMutex); + return _callback; +} + +#ifdef _WIN32 + +static BOOL WINAPI handlerRoutine(DWORD dwCtrlType) +{ + CtrlCHandlerCallback callback = _handler->getCallback(); + if(callback != 0) + { + try + { + callback(dwCtrlType); + } + catch(...) + { + assert(0); + } + } + return TRUE; +} + + +CtrlCHandler::CtrlCHandler(CtrlCHandlerCallback callback) +{ + StaticMutex::Lock lock(globalMutex); + if(_handler != 0) + { + throw CtrlCHandlerException(__FILE__, __LINE__); + } + else + { + _callback = callback; + _handler = this; + lock.release(); + SetConsoleCtrlHandler(handlerRoutine, TRUE); + } +} + +CtrlCHandler::~CtrlCHandler() +{ + SetConsoleCtrlHandler(handlerRoutine, FALSE); + { + StaticMutex::Lock lock(globalMutex); + _handler = 0; + } +} + +#else + +extern "C" +{ + +static void* +sigwaitThread(void*) +{ + sigset_t ctrlCLikeSignals; + sigemptyset(&ctrlCLikeSignals); + sigaddset(&ctrlCLikeSignals, SIGHUP); + sigaddset(&ctrlCLikeSignals, SIGINT); + sigaddset(&ctrlCLikeSignals, SIGTERM); + + // Run until I'm cancelled (in sigwait()) + // + for(;;) + { + int signal = 0; + int rc = sigwait(&ctrlCLikeSignals, &signal); + assert(rc == 0); + + rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0); + assert(rc == 0); + + CtrlCHandlerCallback callback = _handler->getCallback(); + + if(callback != 0) + { + try + { + callback(signal); + } + catch(...) + { + assert(0); + } + } + + rc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0); + assert(rc == 0); + } + return 0; +} +} + +static pthread_t _tid; + +CtrlCHandler::CtrlCHandler(CtrlCHandlerCallback callback) +{ + StaticMutex::Lock lock(globalMutex); + if(_handler != 0) + { + throw CtrlCHandlerException(__FILE__, __LINE__); + } + else + { + _callback = callback; + _handler = this; + lock.release(); + + // We block these CTRL+C like signals in the main thread, + // and by default all other threads will inherit this signal + // disposition. + + sigset_t ctrlCLikeSignals; + sigemptyset(&ctrlCLikeSignals); + sigaddset(&ctrlCLikeSignals, SIGHUP); + sigaddset(&ctrlCLikeSignals, SIGINT); + sigaddset(&ctrlCLikeSignals, SIGTERM); + int rc = pthread_sigmask(SIG_BLOCK, &ctrlCLikeSignals, 0); + assert(rc == 0); + + // Joinable thread + rc = pthread_create(&_tid, 0, sigwaitThread, 0); + assert(rc == 0); + } +} + +CtrlCHandler::~CtrlCHandler() +{ + int rc = pthread_cancel(_tid); + assert(rc == 0); + void* status = 0; + rc = pthread_join(_tid, &status); + assert(rc == 0); + assert(status == PTHREAD_CANCELED); + + { + StaticMutex::Lock lock(globalMutex); + _handler = 0; + } +} + +#endif + diff --git a/cpp/src/IceUtil/Makefile b/cpp/src/IceUtil/Makefile index 88e1640354c..a448d7ec787 100644 --- a/cpp/src/IceUtil/Makefile +++ b/cpp/src/IceUtil/Makefile @@ -26,6 +26,8 @@ OBJS = Exception.o \ Cond.o \ Thread.o \ ThreadException.o \ + StaticMutex.o \ + CtrlCHandler.o \ Time.o \ InputUtil.o \ OutputUtil.o \ 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; + diff --git a/cpp/src/IceUtil/iceutil.dsp b/cpp/src/IceUtil/iceutil.dsp index 146da953868..f4a6eda142b 100644 --- a/cpp/src/IceUtil/iceutil.dsp +++ b/cpp/src/IceUtil/iceutil.dsp @@ -114,6 +114,10 @@ SOURCE=.\Cond.cpp # End Source File
# Begin Source File
+SOURCE=.\CtrlCHandler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\Exception.cpp
# End Source File
# Begin Source File
@@ -134,6 +138,10 @@ SOURCE=.\RWRecMutex.cpp # End Source File
# Begin Source File
+SOURCE=.\StaticMutex.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\Thread.cpp
# End Source File
# Begin Source File
@@ -170,6 +178,10 @@ SOURCE=..\..\include\IceUtil\Config.h # End Source File
# Begin Source File
+SOURCE=..\..\include\IceUtil\CtrlCHandler.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\IceUtil\Exception.h
# End Source File
# Begin Source File
@@ -218,6 +230,10 @@ SOURCE=..\..\include\IceUtil\Shared.h # End Source File
# Begin Source File
+SOURCE=..\..\include\IceUtil\StaticMutex.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\IceUtil\Thread.h
# End Source File
# Begin Source File
|