diff --git a/src/sys/threadbase.h b/src/sys/threadbase.h index a5db2c17..1b0d24b7 100644 --- a/src/sys/threadbase.h +++ b/src/sys/threadbase.h @@ -26,16 +26,17 @@ # include #elif defined HAVE_PTHREAD_H # include -#elif defined _XBOX -# include -# undef near /* Fuck Microsoft */ -# undef far /* Fuck Microsoft again */ -#elif defined _WIN32 +#else +# error No threading support yet :( +#endif + +/* XXX: workaround for a bug in Visual Studio 2012 and 2013! + * https://connect.microsoft.com/VisualStudio/feedback/details/747145 */ +#if defined(_MSC_VER) && (_MSC_VER < 1900) +# define LOL_VISUAL_STUDIO_BUG_747145_WORKAROUND 1 # include # undef near /* Fuck Microsoft */ # undef far /* Fuck Microsoft again */ -#else -# error No threading support yet :( #endif namespace lol @@ -53,8 +54,6 @@ public: /* Nothing */ #elif defined HAVE_PTHREAD_H pthread_mutex_init(&m_mutex, nullptr); -#elif defined _WIN32 - InitializeCriticalSection(&m_mutex); #endif } @@ -67,8 +66,6 @@ public: /* Nothing */ #elif defined HAVE_PTHREAD_H pthread_mutex_destroy(&m_mutex); -#elif defined _WIN32 - DeleteCriticalSection(&m_mutex); #endif } @@ -81,8 +78,6 @@ public: m_mutex.lock(); #elif defined HAVE_PTHREAD_H pthread_mutex_lock(&m_mutex); -#elif defined _WIN32 - EnterCriticalSection(&m_mutex); #endif } @@ -95,8 +90,6 @@ public: return m_mutex.try_lock(); #elif defined HAVE_PTHREAD_H return !pthread_mutex_trylock(&m_mutex); -#elif defined _WIN32 - return !!TryEnterCriticalSection(&m_mutex); #endif } @@ -109,8 +102,6 @@ public: m_mutex.unlock(); #elif defined HAVE_PTHREAD_H pthread_mutex_unlock(&m_mutex); -#elif defined _WIN32 - LeaveCriticalSection(&m_mutex); #endif } @@ -122,8 +113,6 @@ private: std::mutex m_mutex; #elif defined HAVE_PTHREAD_H pthread_mutex_t m_mutex; -#elif defined _WIN32 - CRITICAL_SECTION m_mutex; #endif }; @@ -144,10 +133,6 @@ public: pthread_mutex_init(&m_mutex, nullptr); pthread_cond_init(&m_empty_cond, nullptr); pthread_cond_init(&m_full_cond, nullptr); -#elif defined _WIN32 - m_empty_sem = CreateSemaphore(nullptr, CAPACITY, CAPACITY, nullptr); - m_full_sem = CreateSemaphore(nullptr, 0, CAPACITY, nullptr); - InitializeCriticalSection(&m_mutex); #endif } @@ -161,10 +146,6 @@ public: pthread_cond_destroy(&m_empty_cond); pthread_cond_destroy(&m_full_cond); pthread_mutex_destroy(&m_mutex); -#elif defined _WIN32 - CloseHandle(m_empty_sem); - CloseHandle(m_full_sem); - DeleteCriticalSection(&m_mutex); #endif } @@ -184,9 +165,6 @@ public: while (m_count == CAPACITY) pthread_cond_wait(&m_full_cond, &m_mutex); m_pushers--; -#elif defined _WIN32 - WaitForSingleObject(m_empty_sem, INFINITE); - EnterCriticalSection(&m_mutex); #endif do_push(value); /* Push value */ @@ -202,9 +180,6 @@ public: if (m_poppers) pthread_cond_signal(&m_empty_cond); pthread_mutex_unlock(&m_mutex); -#elif defined _WIN32 - LeaveCriticalSection(&m_mutex); - ReleaseSemaphore(m_full_sem, 1, nullptr); #endif } @@ -236,11 +211,6 @@ public: pthread_mutex_unlock(&m_mutex); return false; } -#elif defined _WIN32 - DWORD status = WaitForSingleObject(m_empty_sem, 0); - if (status == WAIT_TIMEOUT) - return false; - EnterCriticalSection(&m_mutex); #endif do_push(value); /* Push value */ @@ -256,9 +226,6 @@ public: if (m_poppers) pthread_cond_signal(&m_empty_cond); pthread_mutex_unlock(&m_mutex); -#elif defined _WIN32 - LeaveCriticalSection(&m_mutex); - ReleaseSemaphore(m_full_sem, 1, nullptr); #endif return true; @@ -282,9 +249,6 @@ public: while (m_count == 0) pthread_cond_wait(&m_empty_cond, &m_mutex); m_poppers--; -#elif defined _WIN32 - WaitForSingleObject(m_full_sem, INFINITE); - EnterCriticalSection(&m_mutex); #endif T ret = do_pop(); /* Pop value */ @@ -333,11 +297,6 @@ public: pthread_mutex_unlock(&m_mutex); return false; } -#elif defined _WIN32 - DWORD status = WaitForSingleObject(m_full_sem, 0); - if (status == WAIT_TIMEOUT) - return false; - EnterCriticalSection(&m_mutex); #endif ret = do_pop(); /* Pop value */ @@ -391,9 +350,6 @@ private: size_t m_poppers, m_pushers; pthread_mutex_t m_mutex; pthread_cond_t m_empty_cond, m_full_cond; -#elif defined _WIN32 - HANDLE m_empty_sem, m_full_sem; - CRITICAL_SECTION m_mutex; #endif }; @@ -417,9 +373,6 @@ public: pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_create(&m_thread, &attr, trampoline, this); -#elif defined _WIN32 - m_thread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)trampoline, - this, 0, &m_tid); #endif } @@ -428,13 +381,13 @@ public: #if !defined(LOL_FEATURE_THREADS) || !LOL_FEATURE_THREADS /* Nothing */ #elif LOL_FEATURE_CXX11_THREADS - /* FIXME: this does not work in Visual Studio 2013! */ - //m_thread.join(); +# if LOL_VISUAL_STUDIO_BUG_747145_WORKAROUND m_thread.detach(); +# else + m_thread.join(); +# endif #elif defined HAVE_PTHREAD_H pthread_join(m_thread, nullptr); -#elif defined _WIN32 - WaitForSingleObject(m_thread, INFINITE); #endif } @@ -445,6 +398,9 @@ private: static void trampoline(thread_base *that) { that->m_function(); +# if LOL_VISUAL_STUDIO_BUG_747145_WORKAROUND + ExitThread(0); +# endif } #else static void *trampoline(void *data) @@ -463,9 +419,6 @@ private: std::thread m_thread; #elif defined HAVE_PTHREAD_H pthread_t m_thread; -#elif defined _WIN32 - HANDLE m_thread; - DWORD m_tid; #endif };