]> git.sesse.net Git - vlc/blobdiff - modules/demux/live555.cpp
live555 timeout prevention thread fixes
[vlc] / modules / demux / live555.cpp
index 8cf53f19e74c3ad3b4c06247ea5be8ec65497111..4e7f3035e05d075115c62d60646d477bdb7962b3 100644 (file)
@@ -48,6 +48,7 @@
 
 #include <iostream>
 #include <limits.h>
+#include <assert.h>
 
 
 #if defined( WIN32 )
@@ -160,11 +161,9 @@ typedef struct
 
 struct timeout_thread_t
 {
-    VLC_COMMON_MEMBERS
-
-    int64_t      i_remain;
-    bool         b_handle_keep_alive;
     demux_sys_t  *p_sys;
+    vlc_thread_t handle;
+    bool         b_handle_keep_alive;
 };
 
 struct demux_sys_t
@@ -223,7 +222,7 @@ static void StreamRead  ( void *, unsigned int, unsigned int,
 static void StreamClose ( void * );
 static void TaskInterrupt( void * );
 
-static void* TimeoutPrevention( vlc_object_t * );
+static void* TimeoutPrevention( void * );
 
 static unsigned char* parseH264ConfigStr( char const* configStr,
                                           unsigned int& configSize );
@@ -408,16 +407,15 @@ error:
     if( p_sys->i_track ) free( p_sys->track );
     if( p_sys->p_out_asf ) stream_DemuxDelete( p_sys->p_out_asf );
     if( p_sys->rtsp && p_sys->ms ) p_sys->rtsp->teardownMediaSession( *p_sys->ms );
-    if( p_sys->ms ) Medium::close( p_sys->ms );
-    if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp );
-    if( p_sys->env ) p_sys->env->reclaim();
     if( p_sys->p_timeout )
     {
-        vlc_object_kill( p_sys->p_timeout );
-        vlc_thread_join( p_sys->p_timeout );
-        vlc_object_detach( p_sys->p_timeout );
-        vlc_object_release( p_sys->p_timeout );
+        vlc_cancel( p_sys->p_timeout->handle );
+        vlc_join( p_sys->p_timeout->handle, NULL );
+        free( p_sys->p_timeout );
     }
+    if( p_sys->ms ) Medium::close( p_sys->ms );
+    if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp );
+    if( p_sys->env ) p_sys->env->reclaim();
     delete p_sys->scheduler;
     free( p_sys->p_sdp );
     free( p_sys->psz_path );
@@ -450,16 +448,15 @@ static void Close( vlc_object_t *p_this )
     if( p_sys->i_track ) free( p_sys->track );
     if( p_sys->p_out_asf ) stream_DemuxDelete( p_sys->p_out_asf );
     if( p_sys->rtsp && p_sys->ms ) p_sys->rtsp->teardownMediaSession( *p_sys->ms );
-    if( p_sys->ms ) Medium::close( p_sys->ms );
-    if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp );
-    if( p_sys->env ) p_sys->env->reclaim();
     if( p_sys->p_timeout )
     {
-        vlc_object_kill( p_sys->p_timeout );
-        vlc_thread_join( p_sys->p_timeout );
-        vlc_object_detach( p_sys->p_timeout );
-        vlc_object_release( p_sys->p_timeout );
+        vlc_cancel( p_sys->p_timeout->handle );
+        vlc_join( p_sys->p_timeout->handle, NULL );
+        free( p_sys->p_timeout );
     }
+    if( p_sys->ms ) Medium::close( p_sys->ms );
+    if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp );
+    if( p_sys->env ) p_sys->env->reclaim();
     delete p_sys->scheduler;
     free( p_sys->p_sdp );
     free( p_sys->psz_path );
@@ -551,7 +548,8 @@ describe:
 
     psz_options = p_sys->rtsp->sendOptionsCmd( psz_url, psz_user, psz_pwd,
                                                &authenticator );
-    p_sys->b_get_param = strstr( psz_options, "GET_PARAMETER" ) ? true : false ;
+    if( psz_options )
+        p_sys->b_get_param = strstr( psz_options, "GET_PARAMETER" ) ? true : false ;
     delete [] psz_options;
 
     p_sdp = p_sys->rtsp->describeURL( psz_url, &authenticator,
@@ -1043,16 +1041,23 @@ static int Play( demux_t *p_demux )
         if( !p_sys->p_timeout && p_sys->b_get_param )
         {
             msg_Dbg( p_demux, "We have a timeout of %d seconds",  p_sys->i_timeout );
-            p_sys->p_timeout = (timeout_thread_t *)vlc_object_create( p_demux, sizeof(timeout_thread_t) );
-            p_sys->p_timeout->p_sys = p_demux->p_sys; /* lol, object recursion :D */
-            if( vlc_thread_create( p_sys->p_timeout, "liveMedia-timeout", TimeoutPrevention,
-                                   VLC_THREAD_PRIORITY_LOW, true ) )
+            p_sys->p_timeout = (timeout_thread_t *)malloc( sizeof(timeout_thread_t) );
+            if( p_sys->p_timeout )
             {
-                msg_Err( p_demux, "cannot spawn liveMedia timeout thread" );
-                vlc_object_release( p_sys->p_timeout );
+                memset( p_sys->p_timeout, 0, sizeof(timeout_thread_t) );
+                p_sys->p_timeout->p_sys = p_demux->p_sys; /* lol, object recursion :D */
+                if( vlc_clone( &p_sys->p_timeout->handle,  TimeoutPrevention,
+                               p_sys->p_timeout, VLC_THREAD_PRIORITY_LOW ) )
+                {
+                    msg_Err( p_demux, "cannot spawn liveMedia timeout thread" );
+                    free( p_sys->p_timeout );
+                    p_sys->p_timeout = NULL;
+                }
+                else
+                    msg_Dbg( p_demux, "spawned timeout thread" );
             }
-            msg_Dbg( p_demux, "spawned timeout thread" );
-            vlc_object_attach( p_sys->p_timeout, p_demux );
+            else
+                msg_Err( p_demux, "cannot spawn liveMedia timeout thread" );
         }
     }
     p_sys->i_pcr = 0;
@@ -1254,7 +1259,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                         p_sys->env->getResultMsg() );
                     return VLC_EGENERIC;
                 }
-                es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
                 p_sys->i_pcr = 0;
 
                 /* Retrieve RTP-Info values */
@@ -1340,7 +1344,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             p_sys->i_npt_start = 0;
             p_sys->i_pcr = 0;
             p_sys->i_npt = 0.;
-            es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
 
             *pi_int = (int)( INPUT_RATE_DEFAULT / p_sys->ms->scale() + 0.5 );
             return VLC_SUCCESS;
@@ -1711,39 +1714,26 @@ static void TaskInterrupt( void *p_private )
 /*****************************************************************************
  *
  *****************************************************************************/
-static void* TimeoutPrevention( vlc_object_t * p_this )
+static void* TimeoutPrevention( void *p_data )
 {
-    timeout_thread_t *p_timeout = (timeout_thread_t *)p_this;
-    p_timeout->b_die = false;
-    p_timeout->i_remain = (int64_t)p_timeout->p_sys->i_timeout -2;
-    p_timeout->i_remain *= 1000000;
-
-    vlc_thread_ready( p_timeout );
+    timeout_thread_t *p_timeout = (timeout_thread_t *)p_data;
 
-    int canc = vlc_savecancel ();
-    /* Avoid lock */
-    while( vlc_object_alive (p_timeout) )
+    for( ;; )
     {
-        if( p_timeout->i_remain <= 0 )
+        /* Voodoo (= no) thread safety here! *Ahem* */
+        if( p_timeout->b_handle_keep_alive )
         {
             char *psz_bye = NULL;
-            p_timeout->i_remain = (int64_t)p_timeout->p_sys->i_timeout -2;
-            p_timeout->i_remain *= 1000000;
-            msg_Dbg( p_timeout, "reset the timeout timer" );
-            if( p_timeout->b_handle_keep_alive == true )
-            {
-                p_timeout->p_sys->rtsp->getMediaSessionParameter( *p_timeout->p_sys->ms, NULL, psz_bye );
-                p_timeout->p_sys->b_timeout_call = false;
-            }
-            else
-            {
-                p_timeout->p_sys->b_timeout_call = true;
-            }
+            int canc = vlc_savecancel ();
+
+            p_timeout->p_sys->rtsp->getMediaSessionParameter( *p_timeout->p_sys->ms, NULL, psz_bye );
+            vlc_restorecancel (canc);
         }
-        p_timeout->i_remain -= 200000;
-        msleep( 200000 ); /* 200 ms */
+        p_timeout->p_sys->b_timeout_call = !p_timeout->b_handle_keep_alive;
+
+        msleep (((int64_t)p_timeout->p_sys->i_timeout - 2) * CLOCK_FREQ);
     }
-    vlc_restorecancel (canc);
+    assert(0); /* dead code */
 }
 
 /*****************************************************************************