From f64fd9acd66302b78d0282bcdb3011b4c6906733 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Thu, 1 Mar 2007 20:36:11 +0000 Subject: [PATCH] Start cleaning up VLM + fixed vlm_New() race condition. --- include/vlc_vlm.h | 105 +------------- src/control/vlm.c | 2 +- src/input/vlm.c | 293 ++++++++++++++++++++++----------------- src/input/vlm_internal.h | 123 ++++++++++++++++ src/misc/objects.c | 1 + 5 files changed, 296 insertions(+), 228 deletions(-) create mode 100644 src/input/vlm_internal.h diff --git a/include/vlc_vlm.h b/include/vlc_vlm.h index 0a2c3ab685..315af5eb01 100644 --- a/include/vlc_vlm.h +++ b/include/vlc_vlm.h @@ -36,77 +36,6 @@ extern "C" { #include /* VLM specific - structures and functions */ -enum -{ - VOD_TYPE = 0, - BROADCAST_TYPE, - SCHEDULE_TYPE, -}; - -typedef struct -{ - /* instance name */ - char *psz_name; - - /* "playlist" index */ - int i_index; - - input_item_t item; - input_thread_t *p_input; - -} vlm_media_instance_t; - -struct vlm_media_t -{ - vlc_bool_t b_enabled; - int i_type; - - /* name "media" is reserved */ - char *psz_name; - input_item_t item; - - /* "playlist" */ - int i_input; - char **input; - - int i_option; - char **option; - - char *psz_output; - - /* only for broadcast */ - vlc_bool_t b_loop; - - /* only for vod */ - vod_media_t *vod_media; - char *psz_vod_output; - char *psz_mux; - - /* actual input instances */ - int i_instance; - vlm_media_instance_t **instance; - -}; - -struct vlm_schedule_t -{ - /* names "schedule" is reserved */ - char *psz_name; - vlc_bool_t b_enabled; - /* list of commands to execute on date */ - int i_command; - char **command; - - /* the date of 1st execution */ - mtime_t i_date; - - /* if != 0 repeat schedule every (period) */ - mtime_t i_period; - /* number of times you have to repeat - i_repeat < 0 : endless repeat */ - int i_repeat; - -}; /* ok, here is the structure of a vlm_message: The parent node is ( name_of_the_command , NULL ), or @@ -122,42 +51,14 @@ struct vlm_message_t }; -struct vlm_t -{ - VLC_COMMON_MEMBERS - - vlc_mutex_t lock; - - int i_media; - vlm_media_t **media; - - int i_vod; - vod_t *vod; - - int i_schedule; - vlm_schedule_t **schedule; -}; - - #define vlm_New( a ) __vlm_New( VLC_OBJECT(a) ) VLC_EXPORT( vlm_t *, __vlm_New, ( vlc_object_t * ) ); -VLC_EXPORT( void, vlm_Delete, ( vlm_t * ) ); -VLC_EXPORT( int, vlm_ExecuteCommand, ( vlm_t *, const char *, vlm_message_t ** ) ); -VLC_EXPORT( void, vlm_MessageDelete, ( vlm_message_t * ) ); -VLC_EXPORT( vlm_media_t *, vlm_MediaNew, ( vlm_t *, const char *, int ) ); -VLC_EXPORT( void, vlm_MediaDelete, ( vlm_t *, vlm_media_t *, const char * ) ); -VLC_EXPORT( int, vlm_MediaSetup, ( vlm_t *, vlm_media_t *, const char *, const char * ) ); -VLC_EXPORT( int, vlm_MediaControl, ( vlm_t *, vlm_media_t *, const char *, const char *, const char * ) ); -VLC_EXPORT( vlm_media_t* , vlm_MediaSearch,( vlm_t *, const char *) ); -VLC_EXPORT( vlm_schedule_t *, vlm_ScheduleNew, ( vlm_t *, const char * ) ); -VLC_EXPORT( void, vlm_ScheduleDelete, ( vlm_t *, vlm_schedule_t *, const char * ) ); -VLC_EXPORT( int, vlm_ScheduleSetup, ( vlm_schedule_t *, const char *, const char * ) ); -VLC_EXPORT( int, vlm_MediaVodControl, ( void *, vod_media_t *, const char *, int, va_list ) ); -VLC_EXPORT( int, vlm_Save, ( vlm_t *, const char * ) ); -VLC_EXPORT( int, vlm_Load, ( vlm_t *, const char * ) ); +VLC_EXPORT( void, vlm_Delete, ( vlm_t * ) ); +VLC_EXPORT( int, vlm_ExecuteCommand, ( vlm_t *, const char *, vlm_message_t ** ) ); VLC_EXPORT( vlm_message_t *, vlm_MessageNew, ( const char *, const char *, ... ) ); VLC_EXPORT( vlm_message_t *, vlm_MessageAdd, ( vlm_message_t *, vlm_message_t * ) ); +VLC_EXPORT( void, vlm_MessageDelete, ( vlm_message_t * ) ); #ifdef __cpluplus } diff --git a/src/control/vlm.c b/src/control/vlm.c index 78dced5b15..f23b2f2b76 100644 --- a/src/control/vlm.c +++ b/src/control/vlm.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include "../input/vlm_internal.h" static void InitVLM( libvlc_instance_t *p_instance ) { diff --git a/src/input/vlm.c b/src/input/vlm.c index 21298321b0..976306923c 100644 --- a/src/input/vlm.c +++ b/src/input/vlm.c @@ -45,6 +45,7 @@ #include "input_internal.h" #include #include +#include "vlm_internal.h" #include #include @@ -63,6 +64,18 @@ static int Load( vlm_t *, char * ); static int ExecuteCommand( vlm_t *, const char *, vlm_message_t ** ); static int Manage( vlc_object_t * ); +static int vlm_Save( vlm_t *p_vlm, const char *psz_file ); +static int vlm_Load( vlm_t *p_vlm, const char *psz_file ); + + +static vlm_schedule_t *vlm_ScheduleNew( vlm_t *vlm, const char *psz_name ); +static void vlm_ScheduleDelete( vlm_t *vlm, vlm_schedule_t *sched, const char *psz_name ); +static int vlm_ScheduleSetup( vlm_schedule_t *schedule, const char *psz_cmd, + const char *psz_value ); + +static int vlm_MediaVodControl( void *, vod_media_t *, const char *, int, va_list ); + + /***************************************************************************** * vlm_New: *****************************************************************************/ @@ -72,30 +85,37 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) vlm_t *p_vlm = NULL; char *psz_vlmconf; - /* to be sure to avoid multiple creation */ - var_Create( p_this->p_libvlc_global, "vlm_mutex", VLC_VAR_MUTEX ); - var_Get( p_this->p_libvlc_global, "vlm_mutex", &lockval ); + /* Avoid multiple creation */ + if( var_Create( p_this->p_libvlc_global, "vlm_mutex", VLC_VAR_MUTEX ) || + var_Get( p_this->p_libvlc_global, "vlm_mutex", &lockval ) ) + return NULL; + vlc_mutex_lock( lockval.p_address ); - if( !(p_vlm = vlc_object_find( p_this, VLC_OBJECT_VLM, FIND_ANYWHERE )) ) + p_vlm = vlc_object_find( p_this, VLC_OBJECT_VLM, FIND_ANYWHERE ); + if( p_vlm ) { - msg_Info( p_this, "creating VLM" ); - if( ( p_vlm = vlc_object_create( p_this, VLC_OBJECT_VLM ) ) == NULL ) - { - vlc_mutex_unlock( lockval.p_address ); - return NULL; - } + vlc_object_yield( p_vlm ); + vlc_mutex_unlock( lockval.p_address ); + return p_vlm; + } - vlc_mutex_init( p_this->p_libvlc, &p_vlm->lock ); - TAB_INIT( p_vlm->i_media, p_vlm->media ); - TAB_INIT( p_vlm->i_schedule, p_vlm->schedule ); - p_vlm->i_vod = 0; - p_vlm->vod = NULL; + msg_Dbg( p_this, "creating VLM" ); - vlc_object_yield( p_vlm ); - vlc_object_attach( p_vlm, p_this->p_libvlc ); + p_vlm = vlc_object_create( p_this, VLC_OBJECT_VLM ); + if( !p_vlm ) + { + vlc_mutex_unlock( lockval.p_address ); + return NULL; } - vlc_mutex_unlock( lockval.p_address ); + + vlc_mutex_init( p_this->p_libvlc, &p_vlm->lock ); + TAB_INIT( p_vlm->i_media, p_vlm->media ); + TAB_INIT( p_vlm->i_schedule, p_vlm->schedule ); + p_vlm->i_vod = 0; + p_vlm->vod = NULL; + vlc_object_yield( p_vlm ); + vlc_object_attach( p_vlm, p_this->p_libvlc ); if( vlc_thread_create( p_vlm, "vlm thread", Manage, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) @@ -105,9 +125,8 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) return NULL; } - /* Try loading the vlm conf file given by --vlm-conf */ - psz_vlmconf = config_GetPsz( p_vlm, "vlm-conf" ); - + /* Load our configuration file */ + psz_vlmconf = var_CreateGetString( p_vlm, "vlm-conf" ); if( psz_vlmconf && *psz_vlmconf ) { vlm_message_t *p_message = NULL; @@ -117,17 +136,19 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) asprintf(&psz_buffer, "load %s", psz_vlmconf ); if( psz_buffer ) { - msg_Dbg( p_this, psz_buffer); - if( vlm_ExecuteCommand( p_vlm, psz_buffer, &p_message ) ){ + msg_Dbg( p_this, psz_buffer ); + if( vlm_ExecuteCommand( p_vlm, psz_buffer, &p_message ) ) msg_Warn( p_this, "error while loading the configuration file" ); - } + vlm_MessageDelete(p_message); free(psz_buffer); } - } - free(psz_vlmconf); + } + free(psz_vlmconf); - return p_vlm; + vlc_mutex_unlock( lockval.p_address ); + + return p_vlm; } /***************************************************************************** @@ -137,6 +158,7 @@ void vlm_Delete( vlm_t *p_vlm ) { vlc_value_t lockval; + msg_Err( p_vlm, "vlm_Delete called" ); var_Get( p_vlm->p_libvlc_global, "vlm_mutex", &lockval ); vlc_mutex_lock( lockval.p_address ); @@ -151,16 +173,18 @@ void vlm_Delete( vlm_t *p_vlm ) p_vlm->b_die = VLC_TRUE; vlc_thread_join( p_vlm ); + vlc_object_detach( p_vlm ); + vlc_mutex_destroy( &p_vlm->lock ); - while( p_vlm->i_media ) vlm_MediaDelete( p_vlm, p_vlm->media[0], NULL ); - FREENULL( p_vlm->media ); + while( p_vlm->i_media ) + vlm_MediaDelete( p_vlm, p_vlm->media[0], NULL ); + TAB_CLEAN( p_vlm->i_media, p_vlm->media ); - while( p_vlm->i_schedule ) vlm_ScheduleDelete( p_vlm, - p_vlm->schedule[0], NULL ); - FREENULL( p_vlm->schedule ); + while( p_vlm->i_schedule ) + vlm_ScheduleDelete( p_vlm, p_vlm->schedule[0], NULL ); + TAB_CLEAN( p_vlm->schedule, p_vlm->schedule ); - vlc_object_detach( p_vlm ); vlc_object_destroy( p_vlm ); vlc_mutex_unlock( lockval.p_address ); } @@ -180,77 +204,6 @@ int vlm_ExecuteCommand( vlm_t *p_vlm, const char *psz_command, return i_result; } -/***************************************************************************** - * vlm_Save: - *****************************************************************************/ -int vlm_Save( vlm_t *p_vlm, const char *psz_file ) -{ - FILE *file; - char *psz_save; - - if( !p_vlm || !psz_file ) return 1; - - file = utf8_fopen( psz_file, "wt" ); - if( file == NULL ) return 1; - - psz_save = Save( p_vlm ); - if( psz_save == NULL ) - { - fclose( file ); - return 1; - } - fwrite( psz_save, strlen( psz_save ), 1, file ); - fclose( file ); - free( psz_save ); - - return 0; -} - -/***************************************************************************** - * vlm_Load: - *****************************************************************************/ -int vlm_Load( vlm_t *p_vlm, const char *psz_file ) -{ - stream_t *p_stream; - int64_t i_size; - char *psz_buffer; - - if( !p_vlm || !psz_file ) return 1; - - p_stream = stream_UrlNew( p_vlm, psz_file ); - if( p_stream == NULL ) return 1; - - if( stream_Seek( p_stream, 0 ) != 0 ) - { - stream_Delete( p_stream ); - return 2; - } - - i_size = stream_Size( p_stream ); - - psz_buffer = malloc( i_size + 1 ); - if( !psz_buffer ) - { - stream_Delete( p_stream ); - return 2; - } - - stream_Read( p_stream, psz_buffer, i_size ); - psz_buffer[ i_size ] = '\0'; - - stream_Delete( p_stream ); - - if( Load( p_vlm, psz_buffer ) ) - { - free( psz_buffer ); - return 3; - } - - free( psz_buffer ); - - return 0; -} - static const char quotes[] = "\"'"; /** @@ -891,6 +844,80 @@ vlm_media_t *vlm_MediaSearch( vlm_t *vlm, const char *psz_name ) return NULL; } +/***************************************************************************** + * vlm_Save: + *****************************************************************************/ +static int vlm_Save( vlm_t *p_vlm, const char *psz_file ) +{ + FILE *file; + char *psz_save; + + if( !p_vlm || !psz_file ) + return 1; + + file = utf8_fopen( psz_file, "wt" ); + if( file == NULL ) return 1; + + psz_save = Save( p_vlm ); + if( psz_save == NULL ) + { + fclose( file ); + return 1; + } + fwrite( psz_save, strlen( psz_save ), 1, file ); + fclose( file ); + free( psz_save ); + + return 0; +} + +/***************************************************************************** + * vlm_Load: + *****************************************************************************/ +static int vlm_Load( vlm_t *p_vlm, const char *psz_file ) +{ + stream_t *p_stream; + int64_t i_size; + char *psz_buffer; + + if( !p_vlm || !psz_file ) + return 1; + + p_stream = stream_UrlNew( p_vlm, psz_file ); + if( p_stream == NULL ) return 1; + + if( stream_Seek( p_stream, 0 ) != 0 ) + { + stream_Delete( p_stream ); + return 2; + } + + i_size = stream_Size( p_stream ); + + psz_buffer = malloc( i_size + 1 ); + if( !psz_buffer ) + { + stream_Delete( p_stream ); + return 2; + } + + stream_Read( p_stream, psz_buffer, i_size ); + psz_buffer[ i_size ] = '\0'; + + stream_Delete( p_stream ); + + if( Load( p_vlm, psz_buffer ) ) + { + free( psz_buffer ); + return 3; + } + + free( psz_buffer ); + + return 0; +} + + /***************************************************************************** * Media handling *****************************************************************************/ @@ -1400,7 +1427,7 @@ static int64_t vlm_Date(void) #endif } -vlm_schedule_t *vlm_ScheduleNew( vlm_t *vlm, const char *psz_name ) +static vlm_schedule_t *vlm_ScheduleNew( vlm_t *vlm, const char *psz_name ) { vlm_schedule_t *p_sched = malloc( sizeof( vlm_schedule_t ) ); @@ -1428,7 +1455,7 @@ vlm_schedule_t *vlm_ScheduleNew( vlm_t *vlm, const char *psz_name ) } /* for now, simple delete. After, del with options (last arg) */ -void vlm_ScheduleDelete( vlm_t *vlm, vlm_schedule_t *sched, +static void vlm_ScheduleDelete( vlm_t *vlm, vlm_schedule_t *sched, const char *psz_name ) { if( sched == NULL ) return; @@ -1462,7 +1489,7 @@ static vlm_schedule_t *vlm_ScheduleSearch( vlm_t *vlm, const char *psz_name ) } /* Ok, setup schedule command will be able to support only one (argument value) at a time */ -int vlm_ScheduleSetup( vlm_schedule_t *schedule, const char *psz_cmd, +static int vlm_ScheduleSetup( vlm_schedule_t *schedule, const char *psz_cmd, const char *psz_value ) { if( !strcmp( psz_cmd, "enabled" ) ) @@ -2380,8 +2407,8 @@ static char *Save( vlm_t *vlm ) /***************************************************************************** * Manage: *****************************************************************************/ -int vlm_MediaVodControl( void *p_private, vod_media_t *p_vod_media, - const char *psz_id, int i_query, va_list args ) +static int vlm_MediaVodControl( void *p_private, vod_media_t *p_vod_media, + const char *psz_id, int i_query, va_list args ) { vlm_t *vlm = (vlm_t *)p_private; int i, i_ret = VLC_EGENERIC; @@ -2590,23 +2617,39 @@ static int Manage( vlc_object_t* p_object ) vlm_t *__vlm_New( vlc_object_t *a ) { msg_Err( a, "VideoLAN manager support is disabled" ); - return 0; + return NULL; +} +void vlm_Delete( vlm_t *a ) +{ + ; +} +int vlm_ExecuteCommand( vlm_t *a, char *b, vlm_message_t **c ) +{ + return -1; +} +void vlm_MessageDelete( vlm_message_t *a ) +{ + ; +} +vlm_media_t *vlm_MediaNew( vlm_t *a, char *b, int c ) +{ + return NULL; +} +vlm_media_t *vlm_MediaSearch (vlm_t *a, const char *b ) +{ + return NULL; +} +void vlm_MediaDelete( vlm_t *a, vlm_media_t *b, char *c ) +{ + ; +} +int vlm_MediaSetup( vlm_t *a, vlm_media_t *b, char *c, char *d ) +{ + return -1; } -void vlm_Delete( vlm_t *a ){} -int vlm_ExecuteCommand( vlm_t *a, char *b, vlm_message_t **c ){ return -1; } -void vlm_MessageDelete( vlm_message_t *a ){} -vlm_media_t *vlm_MediaNew( vlm_t *a, char *b, int c ){ return NULL; } -vlm_media_t *vlm_MediaSearch (vlm_t *a, const char *b ) { return NULL; } -void vlm_MediaDelete( vlm_t *a, vlm_media_t *b, char *c ){} -int vlm_MediaSetup( vlm_t *a, vlm_media_t *b, char *c, char *d ){ return -1; } int vlm_MediaControl( vlm_t *a, vlm_media_t *b, char *c, char *d, char *e ) - { return -1; } -vlm_schedule_t * vlm_ScheduleNew( vlm_t *a, char *b ){ return NULL; } -void vlm_ScheduleDelete( vlm_t *a, vlm_schedule_t *b, char *c ){} -int vlm_ScheduleSetup( vlm_schedule_t *a, char *b, char *c ){ return -1; } -int vlm_MediaVodControl( void *a, vod_media_t *b, char *c, int d, va_list e ) - { return -1; } -int vlm_Save( vlm_t *a, char *b ){ return -1; } -int vlm_Load( vlm_t *a, char *b ){ return -1; } +{ + return -1; +} #endif /* ENABLE_VLM */ diff --git a/src/input/vlm_internal.h b/src/input/vlm_internal.h new file mode 100644 index 0000000000..fdf431dff3 --- /dev/null +++ b/src/input/vlm_internal.h @@ -0,0 +1,123 @@ +/***************************************************************************** + * vlm_internal.h: Internal vlm structures + ***************************************************************************** + * Copyright (C) 1998-2006 the VideoLAN team + * $Id$ + * + * Authors: Laurent Aimar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef _VLM_INTERNAL_H +#define _VLM_INTERNAL_H 1 + +#include + + +enum +{ + VOD_TYPE = 0, + BROADCAST_TYPE, + SCHEDULE_TYPE, +}; + +typedef struct +{ + /* instance name */ + char *psz_name; + + /* "playlist" index */ + int i_index; + + input_item_t item; + input_thread_t *p_input; + +} vlm_media_instance_t; + +struct vlm_media_t +{ + vlc_bool_t b_enabled; + int i_type; + + /* name "media" is reserved */ + char *psz_name; + input_item_t item; + + /* "playlist" */ + int i_input; + char **input; + + int i_option; + char **option; + + char *psz_output; + + /* only for broadcast */ + vlc_bool_t b_loop; + + /* only for vod */ + vod_media_t *vod_media; + char *psz_vod_output; + char *psz_mux; + + /* actual input instances */ + int i_instance; + vlm_media_instance_t **instance; +}; + +struct vlm_schedule_t +{ + /* names "schedule" is reserved */ + char *psz_name; + vlc_bool_t b_enabled; + /* list of commands to execute on date */ + int i_command; + char **command; + + /* the date of 1st execution */ + mtime_t i_date; + + /* if != 0 repeat schedule every (period) */ + mtime_t i_period; + /* number of times you have to repeat + i_repeat < 0 : endless repeat */ + int i_repeat; +}; + + +struct vlm_t +{ + VLC_COMMON_MEMBERS + + vlc_mutex_t lock; + + int i_media; + vlm_media_t **media; + + int i_vod; + vod_t *vod; + + int i_schedule; + vlm_schedule_t **schedule; +}; + +vlm_media_t *vlm_MediaNew( vlm_t *, const char *, int ); +void vlm_MediaDelete( vlm_t *, vlm_media_t *, const char * ); +int vlm_MediaSetup( vlm_t *, vlm_media_t *, const char *, const char * ); +int vlm_MediaControl( vlm_t *, vlm_media_t *, const char *, const char *, const char * ); +vlm_media_t *vlm_MediaSearch( vlm_t *, const char *); + +#endif diff --git a/src/misc/objects.c b/src/misc/objects.c index 717efb5330..04be619800 100644 --- a/src/misc/objects.c +++ b/src/misc/objects.c @@ -55,6 +55,7 @@ #include "vlc_httpd.h" #include "vlc_vlm.h" +#include "input/vlm_internal.h" #include "vlc_vod.h" #include "vlc_tls.h" #include "vlc_xml.h" -- 2.39.5