Skip to content

Commit

Permalink
win32: make thread killed flag atomic
Browse files Browse the repository at this point in the history
Setting the flag in APC had the benefit of not needing atomicity, but
it meant the flag only got set at the next opportunity to run APC's.

Especially vlc_testcancel() is not an alertable function, so it would
typically be slower. If the thread did not go to alertable sleep, then
vlc_testcancel() would not work at all.

Since vlc_cancel() and vlc_testcancel() do not imply any memory
barriers, the loads and stores can be relaxed. That removes most if not
all of the overhead of the atomic operations.
  • Loading branch information
Rémi Denis-Courmont committed May 27, 2016
1 parent 9503a2c commit f2f32ee
Showing 1 changed file with 3 additions and 20 deletions.
23 changes: 3 additions & 20 deletions src/win32/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,7 @@ struct vlc_thread
HANDLE id;

bool killable;
#if IS_INTERRUPTIBLE
bool killed;
#else
atomic_bool killed;
#endif
vlc_cleanup_t *cleaners;

void *(*entry) (void *);
Expand Down Expand Up @@ -478,11 +474,7 @@ static int vlc_clone_attr (vlc_thread_t *p_handle, bool detached,
th->entry = entry;
th->data = data;
th->killable = false; /* not until vlc_entry() ! */
#if IS_INTERRUPTIBLE
th->killed = false;
#else
atomic_init(&th->killed, false);
#endif
th->cleaners = NULL;

/* When using the MSVCRT C library you have to use the _beginthreadex
Expand Down Expand Up @@ -565,19 +557,15 @@ int vlc_set_priority (vlc_thread_t th, int priority)
/* APC procedure for thread cancellation */
static void CALLBACK vlc_cancel_self (ULONG_PTR self)
{
struct vlc_thread *th = (void *)self;

if (likely(th != NULL))
th->killed = true;
(void) self;
}
#endif

void vlc_cancel (vlc_thread_t th)
{
atomic_store_explicit(&th->killed, true, memory_order_relaxed);
#if IS_INTERRUPTIBLE
QueueUserAPC (vlc_cancel_self, th->id, (uintptr_t)th);
#else
atomic_store (&th->killed, true);
#endif
}

Expand Down Expand Up @@ -611,13 +599,8 @@ void vlc_testcancel (void)
return; /* Main thread - cannot be cancelled anyway */
if (!th->killable)
return;
#if IS_INTERRUPTIBLE
if (likely(!th->killed))
return;
#else
if (!atomic_load(&th->killed))
if (!atomic_load_explicit(&th->killed, memory_order_relaxed))
return;
#endif

th->killable = true; /* Do not re-enter cancellation cleanup */

Expand Down

0 comments on commit f2f32ee

Please sign in to comment.