[vlc-devel] commit: De-inline vlc_(test|save|restore)cancel, add some assertions ( Rémi Denis-Courmont )
git version control
git at videolan.org
Sun Jan 25 19:31:53 CET 2009
vlc | branch: master | Rémi Denis-Courmont <rdenis at simphalempin.com> | Sun Jan 25 20:30:48 2009 +0200| [72218fb9b9ba6c9f5a36bd3d3cfb1557a5491452] | committer: Rémi Denis-Courmont
De-inline vlc_(test|save|restore)cancel, add some assertions
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=72218fb9b9ba6c9f5a36bd3d3cfb1557a5491452
---
include/vlc_threads.h | 50 +-----------------
src/libvlccore.sym | 3 +
src/misc/threads.c | 133 +++++++++++++++++++++++++++++++++++--------------
3 files changed, 102 insertions(+), 84 deletions(-)
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 66f0f67..c990832 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -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)
/**
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index f589662..4933f76 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -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
diff --git a/src/misc/threads.c b/src/misc/threads.c
index e35d6b5..f9fb8c5 100644
--- a/src/misc/threads.c
+++ b/src/misc/threads.c
@@ -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;
More information about the vlc-devel
mailing list