diff --git a/NEWS b/NEWS index bea7245cf..c89f8ef92 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,7 @@ ver 0.21 (not yet released) * require GCC 5.0 ver 0.20.16 (not yet released) +* fix crash in debug build on Haiku and other operating systems ver 0.20.15 (2018/01/05) * queue: fix crash after seek failure diff --git a/src/thread/Thread.cxx b/src/thread/Thread.cxx index 3453ab93e..d1f18522f 100644 --- a/src/thread/Thread.cxx +++ b/src/thread/Thread.cxx @@ -86,6 +86,10 @@ Thread::ThreadProc(void *ctx) noexcept { Thread &thread = *(Thread *)ctx; +#ifndef NDEBUG + thread.inside_handle = pthread_self(); +#endif + thread.Run(); return nullptr; diff --git a/src/thread/Thread.hxx b/src/thread/Thread.hxx index 0cac2314b..822943ac3 100644 --- a/src/thread/Thread.hxx +++ b/src/thread/Thread.hxx @@ -41,6 +41,16 @@ class Thread { DWORD id; #else pthread_t handle = pthread_t(); + +#ifndef NDEBUG + /** + * This handle is only used by IsInside(), and is set by the + * thread function. Since #handle is set by pthread_create() + * which is racy, we need this attribute for early checks + * inside the thread function. + */ + pthread_t inside_handle = pthread_t(); +#endif #endif public: @@ -62,8 +72,9 @@ public: #else return handle != pthread_t(); #endif - } + } +#ifndef NDEBUG /** * Check if this thread is the current thread. */ @@ -78,9 +89,10 @@ public: default-constructed values" (comment from libstdc++) - and if both libstdc++ and libc++ get away with this, we can do it as well */ - return pthread_self() == handle; + return pthread_self() == inside_handle; #endif } +#endif void Start(); void Join() noexcept;