summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2018-01-08 09:58:18 +0100
committerMax Kellermann <max@musicpd.org>2018-01-08 09:58:18 +0100
commit2eef4e67165c38c147980ead785bcf7180b53009 (patch)
treead982cd6e8b6032b1531dc5b1f4439da885a9ec3 /src
parentd989dbfec4a16ba8b40209aff7025645c8045681 (diff)
thread/Thread: add debug attribute "inside_handle"
This attribute shall be used only for IsInside() to make this safe against a race condition described in #188: > There is no requirement on the implementation that the ID of the > created thread be available before the newly created thread starts > executing. http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_create.html): This means that on some pthread implementations (e.g. Haiku), the assert(thread.IsInside()) could fail. Closes #188
Diffstat (limited to 'src')
-rw-r--r--src/thread/Thread.cxx4
-rw-r--r--src/thread/Thread.hxx12
2 files changed, 15 insertions, 1 deletions
diff --git a/src/thread/Thread.cxx b/src/thread/Thread.cxx
index de3c46703..21aec1154 100644
--- a/src/thread/Thread.cxx
+++ b/src/thread/Thread.cxx
@@ -86,6 +86,10 @@ Thread::ThreadProc(void *ctx)
{
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 797ae9676..45250c5c7 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:
@@ -79,7 +89,7 @@ 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