De-inline vlc_(test|save|restore)cancel, add some assertions
authorRémi Denis-Courmont <rdenis@simphalempin.com>
Sun, 25 Jan 2009 18:30:48 +0000 (20:30 +0200)
committerRémi Denis-Courmont <rdenis@simphalempin.com>
Sun, 25 Jan 2009 18:30:48 +0000 (20:30 +0200)
include/vlc_threads.h
src/libvlccore.sym
src/misc/threads.c

index 66f0f67..c990832 100644 (file)
@@ -163,59 +163,15 @@ VLC_EXPORT (void, vlc_control_cancel, (int cmd, ...));
 
 #ifndef LIBVLC_USE_PTHREAD_CANCEL
 enum {
-    VLC_SAVE_CANCEL,
-    VLC_RESTORE_CANCEL,
-    VLC_TEST_CANCEL,
     VLC_DO_CANCEL,
     VLC_CLEANUP_PUSH,
     VLC_CLEANUP_POP,
 };
 #endif
 
-/**
- * Save the cancellation state and disable cancellation for the calling thread.
- * This function must be called before entering a piece of code that is not
- * cancellation-safe.
- * @return Previous cancellation state (opaque value).
- */
-static inline int vlc_savecancel (void)
-{
-    int state;
-#if defined (LIBVLC_USE_PTHREAD_CANCEL)
-    (void) pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
-#else
-    vlc_control_cancel (VLC_SAVE_CANCEL, &state);
-#endif
-    return state;
-}
-
-/**
- * Restore the cancellation state for the calling thread.
- * @param state previous state as returned by vlc_savecancel().
- * @return Nothing, always succeeds.
- */
-static inline void vlc_restorecancel (int state)
-{
-#if defined (LIBVLC_USE_PTHREAD_CANCEL)
-    (void) pthread_setcancelstate (state, NULL);
-#else
-    vlc_control_cancel (VLC_RESTORE_CANCEL, state);
-#endif
-}
-
-/**
- * Issues an explicit deferred cancellation point.
- * This has no effect if thread cancellation is disabled.
- * This can be called when there is a rather slow non-sleeping operation.
- */
-static inline void vlc_testcancel (void)
-{
-#if defined (LIBVLC_USE_PTHREAD_CANCEL)
-    pthread_testcancel ();
-#else
-    vlc_control_cancel (VLC_TEST_CANCEL);
-#endif
-}
+VLC_EXPORT( int, vlc_savecancel, (void) );
+VLC_EXPORT( void, vlc_restorecancel, (int state) );
+VLC_EXPORT( void, vlc_testcancel, (void) );
 
 #if defined (LIBVLC_USE_PTHREAD_CANCEL)
 /**
index f589662..4933f76 100644 (file)
@@ -496,6 +496,8 @@ vlc_poll
 vlc_rand_bytes
 vlc_recvmsg
 vlc_release
+vlc_restorecancel
+vlc_savecancel
 vlc_sd_Create
 vlc_sd_GetNames
 vlc_sdp_Start
@@ -506,6 +508,7 @@ vlc_strcasestr
 vlc_strlcpy
 vlc_strtoll
 vlc_submodule_create
+vlc_testcancel
 vlc_thread_create
 __vlc_thread_join
 __vlc_thread_set_priority
index e35d6b5..f9fb8c5 100644 (file)
@@ -805,8 +805,7 @@ void vlc_join (vlc_thread_t handle, void **result)
 {
 #if defined( LIBVLC_USE_PTHREAD )
     int val = pthread_join (handle, result);
-    if (val)
-        vlc_thread_fatal ("joining thread", val, __func__, __FILE__, __LINE__);
+    VLC_THREAD_ASSERT ("joining thread");
 
 #elif defined( UNDER_CE ) || defined( WIN32 )
     do
@@ -825,6 +824,101 @@ void vlc_join (vlc_thread_t handle, void **result)
 #endif
 }
 
+/**
+ * Save the current cancellation state (enabled or disabled), then disable
+ * cancellation for the calling thread.
+ * This function must be called before entering a piece of code that is not
+ * cancellation-safe, unless it can be proven that the calling thread will not
+ * be cancelled.
+ * @return Previous cancellation state (opaque value for vlc_restorecancel()).
+ */
+int vlc_savecancel (void)
+{
+    int state;
+
+#if defined (LIBVLC_USE_PTHREAD_CANCEL)
+    int val = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
+    VLC_THREAD_ASSERT ("saving cancellation");
+
+#else
+    vlc_cancel_t *nfo = vlc_threadvar_get (&cancel_key);
+    if (nfo == NULL)
+        return; /* Main thread - cannot be cancelled anyway */
+
+     state = nfo->killable;
+     nfo->killable = false;
+
+#endif
+    return state;
+}
+
+/**
+ * Restore the cancellation state for the calling thread.
+ * @param state previous state as returned by vlc_savecancel().
+ * @return Nothing, always succeeds.
+ */
+void vlc_restorecancel (int state)
+{
+#if defined (LIBVLC_USE_PTHREAD_CANCEL)
+# ifndef NDEBUG
+    int oldstate, val;
+
+    val = pthread_setcancelstate (state, &oldstate);
+    /* This should fail if an invalid value for given for state */
+    VLC_THREAD_ASSERT ("restoring cancellation");
+
+    if (oldstate != PTHREAD_CANCEL_DISABLE)
+         vlc_thread_fatal ("restoring cancellation while not disabled", EINVAL,
+                           __func__, __FILE__, __LINE__);
+# else
+    pthread_setcancelstate (state, NULL);
+# endif
+
+#else
+    vlc_cancel_t *nfo = vlc_threadvar_get (&cancel_key);
+    assert (state == false || state == true);
+
+    if (nfo == NULL)
+        return; /* Main thread - cannot be cancelled anyway */
+    nfo->killable = state != 0;
+
+#endif
+}
+
+/**
+ * Issues an explicit deferred cancellation point.
+ * This has no effect if thread cancellation is disabled.
+ * This can be called when there is a rather slow non-sleeping operation.
+ * This is also used to force a cancellation point in a function that would
+ * otherwise "not always" be a one (block_FifoGet() is an example).
+ */
+void vlc_testcancel (void)
+{
+#if defined (LIBVLC_USE_PTHREAD_CANCEL)
+    pthread_testcancel ();
+
+#else
+    vlc_cancel_t *nfo = vlc_threadvar_get (&cancel_key);
+    if (nfo == NULL)
+        return; /* Main thread - cannot be cancelled anyway */
+
+    if (nfo->killable && nfo->killed)
+    {
+        for (vlc_cleanup_t *p = nfo->cleaners; p != NULL; p = p->next)
+             p->proc (p->data);
+# if defined (LIBVLC_USE_PTHREAD)
+        pthread_exit (PTHREAD_CANCELLED);
+# elif defined (UNDER_CE)
+        ExitThread(0);
+# elif defined (WIN32)
+        _endthread ();
+# else
+#  error Not implemented!
+# endif
+    }
+#endif
+}
+
 
 struct vlc_thread_boot
 {
@@ -1058,41 +1152,6 @@ void vlc_control_cancel (int cmd, ...)
     va_start (ap, cmd);
     switch (cmd)
     {
-        case VLC_SAVE_CANCEL:
-        {
-            int *p_state = va_arg (ap, int *);
-            *p_state = nfo->killable;
-            nfo->killable = false;
-            break;
-        }
-
-        case VLC_RESTORE_CANCEL:
-        {
-            int state = va_arg (ap, int);
-            nfo->killable = state != 0;
-            break;
-        }
-
-        case VLC_TEST_CANCEL:
-            if (nfo->killable && nfo->killed)
-            {
-                for (vlc_cleanup_t *p = nfo->cleaners; p != NULL; p = p->next)
-                     p->proc (p->data);
-#ifndef WIN32
-                free (nfo);
-#endif
-#if defined (LIBVLC_USE_PTHREAD)
-                pthread_exit (PTHREAD_CANCELLED);
-#elif defined (UNDER_CE)
-                ExitThread(0);
-#elif defined (WIN32)
-                _endthread ();
-#else
-# error Not implemented!
-#endif
-            }
-            break;
-
         case VLC_DO_CANCEL:
             nfo->killed = true;
             break;