[vlc-devel] commit: Object functions: cancellation safety ( 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> | Sun Aug  3 18:44:22 2008 +0300| [2ec60e08db1086b5eb0504bc6fe2d7e398e7355c] | committer: Rémi Denis-Courmont 

Object functions: cancellation safety

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2ec60e08db1086b5eb0504bc6fe2d7e398e7355c
---

 src/misc/objects.c |   40 ++++++++++++++++++++++++++++++++++++++--
 1 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/misc/objects.c b/src/misc/objects.c
index 8e35be1..70a46cd 100644
--- a/src/misc/objects.c
+++ b/src/misc/objects.c
@@ -23,6 +23,9 @@
 /**
  * \file
  * This file contains the functions to handle the vlc_object_t type
+ *
+ * Unless otherwise stated, functions in this file are not cancellation point.
+ * All functions in this file are safe w.r.t. deferred cancellation.
  */
 
 
@@ -97,6 +100,13 @@ static void held_objects_destroy (void *);
 static vlc_mutex_t structure_lock;
 static unsigned    object_counter = 0;
 
+static void close_nocancel (int fd)
+{
+    int canc = vlc_savecancel ();
+    close (fd);
+    vlc_restorecancel (canc);
+}
+
 void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size,
                            int i_type, const char *psz_type )
 {
@@ -200,12 +210,14 @@ void *__vlc_custom_create( vlc_object_t *p_this, size_t i_size,
 
     if( i_type == VLC_OBJECT_LIBVLC )
     {
+        int canc = vlc_savecancel ();
         var_Create( p_new, "list", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
         var_AddCallback( p_new, "list", DumpCommand, NULL );
         var_Create( p_new, "tree", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
         var_AddCallback( p_new, "tree", DumpCommand, NULL );
         var_Create( p_new, "vars", VLC_VAR_STRING | VLC_VAR_ISCOMMAND );
         var_AddCallback( p_new, "vars", DumpCommand, NULL );
+        vlc_restorecancel (canc);
     }
 
     return p_new;
@@ -289,6 +301,8 @@ void __vlc_object_set_destructor( vlc_object_t *p_this,
  * This function destroys an object that has been previously allocated with
  * vlc_object_create. The object's refcount must be zero and it must not be
  * attached to other objects in any way.
+ *
+ * This function must be called with cancellation disabled (currently).
  *****************************************************************************/
 static void vlc_object_destroy( vlc_object_t *p_this )
 {
@@ -516,6 +530,9 @@ int __vlc_object_waitpipe( vlc_object_t *obj )
  * If the object was signaled before the caller locked the object, it is
  * undefined whether the signal will be lost or will wake the process.
  *
+ * This function is a cancellation point. In case of cancellation, the object
+ * will be in locked state.
+ *
  * @return true if the object is dying and should terminate.
  */
 void __vlc_object_wait( vlc_object_t *obj )
@@ -530,6 +547,9 @@ void __vlc_object_wait( vlc_object_t *obj )
  * Waits for the object to be signaled (using vlc_object_signal()), or for
  * a timer to expire. It is asserted that the caller holds the object lock.
  *
+ * This function is a cancellation point. In case of cancellation, the object
+ * will be in locked state.
+ *
  * @return 0 if the object was signaled before the timer expiration, or
  * ETIMEDOUT if the timer expired without any signal.
  */
@@ -575,7 +595,7 @@ void __vlc_object_kill( vlc_object_t *p_this )
     if( fd != -1 )
     {
         msg_Dbg (p_this, "waitpipe: object killed");
-        close (fd);
+        close_nocancel (fd);
     }
 
     vlc_object_signal_unlocked( p_this );
@@ -603,8 +623,12 @@ void * vlc_object_get( int i_id )
     if (caller)
         msg_Dbg (caller, "uses deprecated vlc_object_get(%d)", i_id);
     else
+    {
+        int canc = vlc_savecancel ();
         fprintf (stderr, "main thread uses deprecated vlc_object_get(%d)\n",
                  i_id);
+        vlc_restorecancel (canc);
+    }
 #endif
     vlc_mutex_lock( &structure_lock );
 
@@ -745,7 +769,7 @@ void __vlc_object_yield( vlc_object_t *p_this )
 }
 
 /*****************************************************************************
- * decrement an object refcount
+ * Decrement an object refcount
  * And destroy the object if its refcount reach zero.
  *****************************************************************************/
 void __vlc_object_release( vlc_object_t *p_this )
@@ -814,10 +838,14 @@ void __vlc_object_release( vlc_object_t *p_this )
 
     if( b_should_destroy )
     {
+        int canc;
+
         free( internals->pp_children );
         internals->pp_children = NULL;
         internals->i_children = 0;
+        canc = vlc_savecancel ();
         vlc_object_destroy( p_this );
+        vlc_restorecancel (canc);
     }
 }
 
@@ -1272,6 +1300,7 @@ static void PrintObject( vlc_object_t *p_this, const char *psz_prefix )
     char psz_children[20], psz_refcount[20], psz_thread[30], psz_name[50],
          psz_parent[20];
 
+    int canc = vlc_savecancel ();
     memset( &psz_name, 0, sizeof(psz_name) );
     if( p_this->psz_object_name )
     {
@@ -1312,6 +1341,7 @@ static void PrintObject( vlc_object_t *p_this, const char *psz_prefix )
             p_this->i_object_id, p_this->psz_object_type,
             psz_name, psz_thread, psz_refcount, psz_children,
             psz_parent );
+    vlc_restorecancel (canc);
 }
 
 static void DumpStructure( vlc_object_t *p_this, int i_level, char *psz_foo )
@@ -1509,6 +1539,8 @@ void vlc_refcheck (vlc_object_t *obj)
         if (hlcur->obj == obj)
             return;
 
+    int canc = vlc_savecancel ();
+
     fprintf (stderr, "The %s %s thread object is accessing...\n"
              "the %s %s object without references.\n",
              caller && caller->psz_object_name
@@ -1526,6 +1558,7 @@ void vlc_refcheck (vlc_object_t *obj)
 
     if (++errors == 100)
         fprintf (stderr, "Too many reference errors!\n");
+    vlc_restorecancel (canc);
 }
 
 static void held_objects_destroy (void *data)
@@ -1534,6 +1567,8 @@ static void held_objects_destroy (void *data)
     held_list_t *hl = vlc_threadvar_get (&held_objects);
     vlc_object_t *caller = vlc_threadobj ();
 
+    int canc = vlc_savecancel ();
+
     while (hl != NULL)
     {
         held_list_t *buf = hl->next;
@@ -1549,5 +1584,6 @@ static void held_objects_destroy (void *data)
         free (hl);
         hl = buf;
     }
+    vlc_restorecancel (canc);
 }
 #endif




More information about the vlc-devel mailing list