diff --git a/depends/tthread/fast_mutex.h b/depends/tthread/fast_mutex.h index b4e712f44..4d4b7cc43 100644 --- a/depends/tthread/fast_mutex.h +++ b/depends/tthread/fast_mutex.h @@ -1,5 +1,5 @@ -/* -Copyright (c) 2010 Marcus Geelnard +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2010-2012 Marcus Geelnard This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,7 +47,15 @@ freely, subject to the following restrictions: #endif #if defined(_TTHREAD_WIN32_) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #define __UNDEF_LEAN_AND_MEAN + #endif #include + #ifdef __UNDEF_LEAN_AND_MEAN + #undef WIN32_LEAN_AND_MEAN + #undef __UNDEF_LEAN_AND_MEAN + #endif #else #ifdef _FAST_MUTEX_ASM_ #include @@ -237,3 +245,4 @@ class fast_mutex { } #endif // _FAST_MUTEX_H_ + diff --git a/depends/tthread/tinythread.cpp b/depends/tthread/tinythread.cpp index eb2dce0e6..176bc2ac8 100644 --- a/depends/tthread/tinythread.cpp +++ b/depends/tthread/tinythread.cpp @@ -1,5 +1,5 @@ -/* -Copyright (c) 2010 Marcus Geelnard +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2010-2012 Marcus Geelnard This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -171,13 +171,17 @@ void * thread::wrapper_function(void * aArg) catch(...) { // Uncaught exceptions will terminate the application (default behavior - // according to the C++0x draft) + // according to C++11) std::terminate(); } +#if 0 + // DFHack fix: this code prevents join from freeing thread resources. + // The thread is no longer executing lock_guard guard(ti->mThread->mDataMutex); ti->mThread->mNotAThread = true; +#endif // The thread is responsible for freeing the startup information delete ti; @@ -228,9 +232,16 @@ void thread::join() { #if defined(_TTHREAD_WIN32_) WaitForSingleObject(mHandle, INFINITE); + CloseHandle(mHandle); #elif defined(_TTHREAD_POSIX_) pthread_join(mHandle, NULL); #endif + +#if 1 + // DFHack patch: moved here from the wrapper function + lock_guard guard(mDataMutex); + mNotAThread = true; +#endif } } @@ -242,6 +253,21 @@ bool thread::joinable() const return result; } +void thread::detach() +{ + mDataMutex.lock(); + if(!mNotAThread) + { +#if defined(_TTHREAD_WIN32_) + CloseHandle(mHandle); +#elif defined(_TTHREAD_POSIX_) + pthread_detach(mHandle); +#endif + mNotAThread = true; + } + mDataMutex.unlock(); +} + thread::id thread::get_id() const { if(!joinable()) diff --git a/depends/tthread/tinythread.h b/depends/tthread/tinythread.h index f4f8c5b22..aed7b5856 100644 --- a/depends/tthread/tinythread.h +++ b/depends/tthread/tinythread.h @@ -1,5 +1,5 @@ -/* -Copyright (c) 2010 Marcus Geelnard +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2010-2012 Marcus Geelnard This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,7 +31,7 @@ freely, subject to the following restrictions: /// TinyThread++ is a minimal, portable implementation of basic threading /// classes for C++. /// -/// They closely mimic the functionality and naming of the C++0x standard, and +/// They closely mimic the functionality and naming of the C++11 standard, and /// should be easily replaceable with the corresponding std:: variants. /// /// @section port_sec Portability @@ -39,7 +39,7 @@ freely, subject to the following restrictions: /// classes, while for other systems, the POSIX threads API (pthread) is used. /// /// @section class_sec Classes -/// In order to mimic the threading API of the C++0x standard, subsets of +/// In order to mimic the threading API of the C++11 standard, subsets of /// several classes are provided. The fundamental classes are: /// @li tthread::thread /// @li tthread::mutex @@ -67,8 +67,15 @@ freely, subject to the following restrictions: // Platform specific includes #if defined(_TTHREAD_WIN32_) - #define NOMINMAX + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #define __UNDEF_LEAN_AND_MEAN + #endif #include + #ifdef __UNDEF_LEAN_AND_MEAN + #undef WIN32_LEAN_AND_MEAN + #undef __UNDEF_LEAN_AND_MEAN + #endif #else #include #include @@ -82,22 +89,22 @@ freely, subject to the following restrictions: /// TinyThread++ version (major number). #define TINYTHREAD_VERSION_MAJOR 1 /// TinyThread++ version (minor number). -#define TINYTHREAD_VERSION_MINOR 0 +#define TINYTHREAD_VERSION_MINOR 1 /// TinyThread++ version (full version). #define TINYTHREAD_VERSION (TINYTHREAD_VERSION_MAJOR * 100 + TINYTHREAD_VERSION_MINOR) -// Do we have a fully featured C++0x compiler? +// Do we have a fully featured C++11 compiler? #if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L)) - #define _TTHREAD_CPP0X_ + #define _TTHREAD_CPP11_ #endif -// ...at least partial C++0x? -#if defined(_TTHREAD_CPP0X_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) - #define _TTHREAD_CPP0X_PARTIAL_ +// ...at least partial C++11? +#if defined(_TTHREAD_CPP11_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) + #define _TTHREAD_CPP11_PARTIAL_ #endif // Macro for disabling assignments of objects. -#ifdef _TTHREAD_CPP0X_PARTIAL_ +#ifdef _TTHREAD_CPP11_PARTIAL_ #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ name(const name&) = delete; \ name& operator=(const name&) = delete; @@ -109,18 +116,18 @@ freely, subject to the following restrictions: /// @def thread_local /// Thread local storage keyword. -/// A variable that is declared with the \c thread_local keyword makes the +/// A variable that is declared with the @c thread_local keyword makes the /// value of the variable local to each thread (known as thread-local storage, /// or TLS). Example usage: /// @code /// // This variable is local to each thread. /// thread_local int variable; /// @endcode -/// @note The \c thread_local keyword is a macro that maps to the corresponding -/// compiler directive (e.g. \c __declspec(thread)). While the C++0x standard +/// @note The @c thread_local keyword is a macro that maps to the corresponding +/// compiler directive (e.g. @c __declspec(thread)). While the C++11 standard /// allows for non-trivial types (e.g. classes with constructors and -/// destructors) to be declared with the \c thread_local keyword, most pre-C++0x -/// compilers only allow for trivial types (e.g. \c int). So, to guarantee +/// destructors) to be declared with the @c thread_local keyword, most pre-C++11 +/// compilers only allow for trivial types (e.g. @c int). So, to guarantee /// portable code, only use trivial types for thread local storage. /// @note This directive is currently not supported on Mac OS X (it will give /// a compiler error), since compile-time TLS is not supported in the Mac OS X @@ -128,7 +135,7 @@ freely, subject to the following restrictions: /// not support this directive. /// @hideinitializer -#if !defined(_TTHREAD_CPP0X_) && !defined(thread_local) +#if !defined(_TTHREAD_CPP11_) && !defined(thread_local) #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) #define thread_local __thread #else @@ -138,8 +145,8 @@ freely, subject to the following restrictions: /// Main name space for TinyThread++. -/// This namespace is more or less equivalent to the \c std namespace for the -/// C++0x thread classes. For instance, the tthread::mutex class corresponds to +/// This namespace is more or less equivalent to the @c std namespace for the +/// C++11 thread classes. For instance, the tthread::mutex class corresponds to /// the std::mutex class. namespace tthread { @@ -176,7 +183,7 @@ class mutex { /// Lock the mutex. /// The method will block the calling thread until a lock on the mutex can - /// be obtained. The mutex remains locked until \c unlock() is called. + /// be obtained. The mutex remains locked until @c unlock() is called. /// @see lock_guard inline void lock() { @@ -192,7 +199,7 @@ class mutex { /// Try to lock the mutex. /// The method will try to lock the mutex. If it fails, the function will /// return immediately (non-blocking). - /// @return \c true if the lock was acquired, or \c false if the lock could + /// @return @c true if the lock was acquired, or @c false if the lock could /// not be acquired. inline bool try_lock() { @@ -268,7 +275,7 @@ class recursive_mutex { /// Lock the mutex. /// The method will block the calling thread until a lock on the mutex can - /// be obtained. The mutex remains locked until \c unlock() is called. + /// be obtained. The mutex remains locked until @c unlock() is called. /// @see lock_guard inline void lock() { @@ -282,7 +289,7 @@ class recursive_mutex { /// Try to lock the mutex. /// The method will try to lock the mutex. If it fails, the function will /// return immediately (non-blocking). - /// @return \c true if the lock was acquired, or \c false if the lock could + /// @return @c true if the lock was acquired, or @c false if the lock could /// not be acquired. inline bool try_lock() { @@ -406,7 +413,7 @@ class condition_variable { /// Wait for the condition. /// The function will block the calling thread until the condition variable - /// is woken by \c notify_one(), \c notify_all() or a spurious wake up. + /// is woken by @c notify_one(), @c notify_all() or a spurious wake up. /// @param[in] aMutex A mutex that will be unlocked when the wait operation /// starts, an locked again as soon as the wait operation is finished. template @@ -482,7 +489,7 @@ class thread { class id; /// Default constructor. - /// Construct a \c thread object without an associated thread of execution + /// Construct a @c thread object without an associated thread of execution /// (i.e. non-joinable). thread() : mHandle(0), mNotAThread(true) #if defined(_TTHREAD_WIN32_) @@ -491,7 +498,7 @@ class thread { {} /// Thread starting constructor. - /// Construct a \c thread object with a new thread of execution. + /// Construct a @c thread object with a new thread of execution. /// @param[in] aFunction A function pointer to a function of type: /// void fun(void * arg) /// @param[in] aArg Argument to the thread function. @@ -501,24 +508,34 @@ class thread { thread(void (*aFunction)(void *), void * aArg); /// Destructor. - /// @note If the thread is joinable upon destruction, \c std::terminate() + /// @note If the thread is joinable upon destruction, @c std::terminate() /// will be called, which terminates the process. It is always wise to do - /// \c join() before deleting a thread object. + /// @c join() before deleting a thread object. ~thread(); /// Wait for the thread to finish (join execution flows). + /// After calling @c join(), the thread object is no longer associated with + /// a thread of execution (i.e. it is not joinable, and you may not join + /// with it nor detach from it). void join(); /// Check if the thread is joinable. /// A thread object is joinable if it has an associated thread of execution. bool joinable() const; + /// Detach from the thread. + /// After calling @c detach(), the thread object is no longer assicated with + /// a thread of execution (i.e. it is not joinable). The thread continues + /// execution without the calling thread blocking, and when the thread + /// ends execution, any owned resources are released. + void detach(); + /// Return the thread ID of a thread object. id get_id() const; /// Get the native handle for this thread. - /// @note Under Windows, this is a \c HANDLE, and under POSIX systems, this - /// is a \c pthread_t. + /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this + /// is a @c pthread_t. inline native_handle_type native_handle() { return mHandle; @@ -613,18 +630,18 @@ class thread::id { // Related to - minimal to be able to support chrono. typedef long long __intmax_t; -/// Minimal implementation of the \c ratio class. This class provides enough -/// functionality to implement some basic \c chrono classes. +/// Minimal implementation of the @c ratio class. This class provides enough +/// functionality to implement some basic @c chrono classes. template <__intmax_t N, __intmax_t D = 1> class ratio { public: static double _as_double() { return double(N) / double(D); } }; -/// Minimal implementation of the \c chrono namespace. -/// The \c chrono namespace provides types for specifying time intervals. +/// Minimal implementation of the @c chrono namespace. +/// The @c chrono namespace provides types for specifying time intervals. namespace chrono { /// Duration template class. This class provides enough functionality to - /// implement \c this_thread::sleep_for(). + /// implement @c this_thread::sleep_for(). template > class duration { private: _Rep rep_; @@ -652,7 +669,7 @@ namespace chrono { typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours. } -/// The namespace \c this_thread provides methods for dealing with the +/// The namespace @c this_thread provides methods for dealing with the /// calling thread. namespace this_thread { /// Return the thread ID of the calling thread. diff --git a/library/RemoteServer.cpp b/library/RemoteServer.cpp index 06a9f859c..0a05833ee 100644 --- a/library/RemoteServer.cpp +++ b/library/RemoteServer.cpp @@ -117,6 +117,7 @@ ServerConnection::ServerConnection(CActiveSocket *socket) core_service->finalize(this, &functions); thread = new tthread::thread(threadFn, (void*)this); + thread->detach(); } ServerConnection::~ServerConnection() @@ -124,6 +125,7 @@ ServerConnection::~ServerConnection() in_error = true; socket->Close(); delete socket; + delete thread; for (auto it = plugin_services.begin(); it != plugin_services.end(); ++it) delete it->second; @@ -363,6 +365,7 @@ ServerMain::~ServerMain() { socket->Close(); delete socket; + delete thread; } bool ServerMain::listen(int port) @@ -376,6 +379,7 @@ bool ServerMain::listen(int port) return false; thread = new tthread::thread(threadFn, this); + thread->detach(); return true; }