diff options
author | Max Kellermann <max@musicpd.org> | 2018-01-08 09:58:18 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-01-08 09:58:18 +0100 |
commit | 2eef4e67165c38c147980ead785bcf7180b53009 (patch) | |
tree | ad982cd6e8b6032b1531dc5b1f4439da885a9ec3 /src | |
parent | d989dbfec4a16ba8b40209aff7025645c8045681 (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.cxx | 4 | ||||
-rw-r--r-- | src/thread/Thread.hxx | 12 |
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 |