[vlc-devel] commit: Support for cancelling self and use normal thread variable ( Rémi Denis-Courmont )
git version control
git at videolan.org
Wed Aug 27 22:57:28 CEST 2008
vlc | branch: master | Rémi Denis-Courmont <rdenis at simphalempin.com> | Wed Aug 6 22:56:42 2008 +0300| [f1b595f734a7b5e28635583b7a5e0d49e59da5f3] | committer: Rémi Denis-Courmont
Support for cancelling self and use normal thread variable
__thread is non-standard (and would need mingw 4.3).
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f1b595f734a7b5e28635583b7a5e0d49e59da5f3
---
include/vlc_threads.h | 1 +
src/misc/threads.c | 56 ++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 63e61d1..ee78ad4 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -186,6 +186,7 @@ enum {
VLC_SAVE_CANCEL,
VLC_RESTORE_CANCEL,
VLC_TEST_CANCEL,
+ VLC_DO_CANCEL,
};
#endif
diff --git a/src/misc/threads.c b/src/misc/threads.c
index 97f9f19..f04cfa5 100644
--- a/src/misc/threads.c
+++ b/src/misc/threads.c
@@ -144,6 +144,8 @@ void vlc_pthread_fatal (const char *action, int error,
(void)action; (void)error; (void)file; (void)line;
abort();
}
+
+static vlc_threadvar_t cancel_key;
#endif
/*****************************************************************************
@@ -178,6 +180,9 @@ int vlc_threads_init( void )
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
}
i_initializations++;
@@ -207,6 +212,9 @@ void vlc_threads_end( void )
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 );
@@ -838,42 +846,76 @@ void vlc_thread_cancel (vlc_object_t *obj)
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
- static __thread struct vlc_cancel_t *stack = NULL;
- static __thread bool killed = false, killable = true;
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 *);
- *p_state = killable;
- killable = false;
+ *p_state = nfo->killable;
+ nfo->killable = false;
break;
}
case VLC_RESTORE_CANCEL:
{
int state = va_arg (ap, int);
- killable = state != 0;
+ nfo->killable = state != 0;
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
+ }
+ break;
+
+ case VLC_DO_CANCEL:
+ nfo->killed = true;
break;
}
va_end (ap);
More information about the vlc-devel
mailing list