__thread is non-standard (and would need mingw 4.3).
VLC_SAVE_CANCEL,
VLC_RESTORE_CANCEL,
VLC_TEST_CANCEL,
VLC_SAVE_CANCEL,
VLC_RESTORE_CANCEL,
VLC_TEST_CANCEL,
(void)action; (void)error; (void)file; (void)line;
abort();
}
(void)action; (void)error; (void)file; (void)line;
abort();
}
+
+static vlc_threadvar_t cancel_key;
#endif
/*****************************************************************************
#endif
/*****************************************************************************
vlc_threadvar_create( &thread_object_key, NULL );
#endif
vlc_threadvar_create( &msg_context_global_key, msg_StackDestroy );
vlc_threadvar_create( &thread_object_key, NULL );
#endif
vlc_threadvar_create( &msg_context_global_key, msg_StackDestroy );
+#ifndef LIBVLC_USE_PTHREAD
+ vlc_threadvar_create( &cancel_key, free );
+#endif
if( i_initializations == 1 )
{
vlc_object_release( p_root );
if( i_initializations == 1 )
{
vlc_object_release( p_root );
+#ifndef LIBVLC_USE_PTHREAD
+ vlc_threadvar_delete( &cancel_key );
+#endif
vlc_threadvar_delete( &msg_context_global_key );
#ifndef NDEBUG
vlc_threadvar_delete( &thread_object_key );
vlc_threadvar_delete( &msg_context_global_key );
#ifndef NDEBUG
vlc_threadvar_delete( &thread_object_key );
vlc_cancel (priv->thread_id);
}
vlc_cancel (priv->thread_id);
}
+typedef struct vlc_cleanup_t
+{
+ struct vlc_cleanup_t *next;
+ void (*proc) (void *);
+ void *data;
+} vlc_cleanup_t;
+
+typedef struct vlc_cancel_t
+{
+ vlc_cleanup_t *cleaners;
+ bool killable;
+ bool killed;
+} vlc_cancel_t;
+
void vlc_control_cancel (int cmd, ...)
{
#ifdef LIBVLC_USE_PTHREAD
(void) cmd;
abort();
#else
void vlc_control_cancel (int cmd, ...)
{
#ifdef LIBVLC_USE_PTHREAD
(void) cmd;
abort();
#else
- static __thread struct vlc_cancel_t *stack = NULL;
- static __thread bool killed = false, killable = true;
va_list ap;
va_start (ap, cmd);
va_list ap;
va_start (ap, cmd);
+ vlc_cancel_t *nfo = vlc_threadvar_get (&cancel_key);
+ if (nfo == NULL)
+ {
+ nfo = malloc (sizeof (*nfo));
+ if (nfo == NULL)
+ abort ();
+ nfo->cleaners = NULL;
+ nfo->killed = false;
+ nfo->killable = true;
+ }
+
switch (cmd)
{
case VLC_SAVE_CANCEL:
{
int *p_state = va_arg (ap, int *);
switch (cmd)
{
case VLC_SAVE_CANCEL:
{
int *p_state = va_arg (ap, int *);
- *p_state = killable;
- killable = false;
+ *p_state = nfo->killable;
+ nfo->killable = false;
break;
}
case VLC_RESTORE_CANCEL:
{
int state = va_arg (ap, int);
break;
}
case VLC_RESTORE_CANCEL:
{
int state = va_arg (ap, int);
+ nfo->killable = state != 0;
break;
}
case VLC_TEST_CANCEL:
break;
}
case VLC_TEST_CANCEL:
- if (killable)
-#ifdef WIN32
+ if (nfo->killable && nfo->killed)
+ {
+ for (vlc_cleanup_t *p = nfo->cleaners; p != NULL; p = p->next)
+ p->proc (p->data);
+ free (nfo);
+#if defined (LIBVLC_USE_PTHREAD)
+ pthread_exit (PTHREAD_CANCELLED);
+#elif defined (WIN32)
_endthread ();
#else
# error Not implemented!
#endif
_endthread ();
#else
# error Not implemented!
#endif
+ }
+ break;
+
+ case VLC_DO_CANCEL:
+ nfo->killed = true;