summaryrefslogtreecommitdiff
path: root/lib/thread.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2017-05-30 15:10:52 +0200
committerGitHub <noreply@github.com>2017-05-30 15:10:52 +0200
commitb7218a79037e803e33c42a80f564b2831a79a4fc (patch)
tree255ea2c9e012f6ae0397681fd2fb22f53ae4cab1 /lib/thread.c
parent9ad245006dd4829478521d25c2098031aa792124 (diff)
parent48cdf1a9d6e687abe71421c3cce59b93ab34ac54 (diff)
Merge pull request #563 from qlyoung/enforce-no-pthread-cancellation
lib: enforce thread_cancel() MT-unsafe invariant
Diffstat (limited to 'lib/thread.c')
-rw-r--r--lib/thread.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/thread.c b/lib/thread.c
index 2843a9211e..ccb635a87d 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -377,6 +377,7 @@ thread_master_create (void)
rv->timer->update = rv->background->update = thread_timer_update;
rv->spin = true;
rv->handle_signals = true;
+ rv->owner = pthread_self();
#if defined(HAVE_POLL_CALL)
rv->handler.pfdsize = rv->fd_limit;
@@ -1021,7 +1022,7 @@ thread_cancel_read_or_write (struct thread *thread, short int state)
* Cancel thread from scheduler.
*
* This function is *NOT* MT-safe. DO NOT call it from any other pthread except
- * the one which owns thread->master.
+ * the one which owns thread->master. You will crash.
*/
void
thread_cancel (struct thread *thread)
@@ -1030,8 +1031,10 @@ thread_cancel (struct thread *thread)
struct pqueue *queue = NULL;
struct thread **thread_array = NULL;
- pthread_mutex_lock (&thread->master->mtx);
pthread_mutex_lock (&thread->mtx);
+ pthread_mutex_lock (&thread->master->mtx);
+
+ assert (pthread_self() == thread->master->owner);
switch (thread->type)
{
@@ -1092,8 +1095,8 @@ thread_cancel (struct thread *thread)
thread_add_unuse (thread->master, thread);
done:
- pthread_mutex_unlock (&thread->mtx);
pthread_mutex_unlock (&thread->master->mtx);
+ pthread_mutex_unlock (&thread->mtx);
}
/* Delete all events which has argument value arg. */