signal handler to its previous value after use.
* ./src/libvlc.c: moved signal handling to vlc.c.
* vlc.h: global header for vlc
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc.h,v 1.8 2002/08/14 17:06:53 sam Exp $
+ * $Id: vlc.h,v 1.9 2002/08/19 11:13:44 sam Exp $
*
* 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
vlc_error_t vlc_create ( void );
vlc_error_t vlc_init ( int, char *[] );
vlc_error_t vlc_run ( void );
+vlc_error_t vlc_die ( void );
vlc_error_t vlc_stop ( void );
vlc_error_t vlc_end ( void );
vlc_error_t vlc_destroy ( void );
vlc_t * vlc_create_r ( void );
vlc_error_t vlc_init_r ( vlc_t *, int, char *[] );
vlc_error_t vlc_run_r ( vlc_t * );
+vlc_error_t vlc_die_r ( vlc_t * );
vlc_error_t vlc_stop_r ( vlc_t * );
vlc_error_t vlc_end_r ( vlc_t * );
vlc_error_t vlc_destroy_r ( vlc_t * );
* libvlc.c: main libvlc source
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.c,v 1.27 2002/08/18 13:49:20 sam Exp $
+ * $Id: libvlc.c,v 1.28 2002/08/19 11:13:45 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
#include <stdio.h> /* sprintf() */
#include <string.h> /* strerror() */
#include <stdlib.h> /* free() */
-#include <signal.h> /* SIGHUP, SIGINT, SIGKILL */
#include <vlc/vlc.h>
static void ListModules ( vlc_t * );
static void Version ( void );
-#ifndef WIN32
-static void InitSignalHandler ( void );
-static void FatalSignalHandler ( int i_signal );
-#endif
-
#ifdef WIN32
static void ShowConsole ( void );
#endif
* vlc_create: allocate a vlc_t structure, and initialize libvlc if needed.
*****************************************************************************
* This function allocates a vlc_t structure and returns NULL in case of
- * failure. Also, the thread system and the signal handlers are initialized.
+ * failure. Also, the thread system is initialized.
*****************************************************************************/
vlc_error_t vlc_create( void )
{
- vlc_t * p_vlc = vlc_create_r();
- return p_vlc ? VLC_SUCCESS : VLC_EGENERIC;
+ vlc_t * p_vlc;
+ vlc_bool_t b_failed = VLC_FALSE;
+
+ /* This gives us a rather good protection against concurrent calls, but
+ * an additional check will be necessary for complete thread safety. */
+ if( i_vlc )
+ {
+ return VLC_EGENERIC;
+ }
+
+ p_vlc = vlc_create_r();
+
+ if( p_vlc == NULL )
+ {
+ return VLC_EGENERIC;
+ }
+
+ /* We have created an object, which ensures us that p_global_lock has
+ * been properly initialized. We can now atomically check that we are
+ * the only p_vlc object. */
+ vlc_mutex_lock( p_vlc->p_global_lock );
+ if( i_vlc != 1 )
+ {
+ b_failed = VLC_TRUE;
+ }
+ vlc_mutex_unlock( p_vlc->p_global_lock );
+
+ /* There can be only one */
+ if( b_failed )
+ {
+ vlc_destroy_r( p_vlc );
+ return VLC_EGENERIC;
+ }
+
+ return VLC_SUCCESS;
}
vlc_t * vlc_create_r( void )
vlc_mutex_init( p_vlc, &p_vlc->config_lock );
vlc_mutex_init( p_vlc, &p_vlc->structure_lock );
- /* Set signal handling policy for all threads */
-#ifndef WIN32
- InitSignalHandler( );
-#endif
-
/* Store our newly allocated structure in the global list */
vlc_mutex_lock( p_vlc->p_global_lock );
pp_vlc = realloc( pp_vlc, (i_vlc+1) * sizeof( vlc_t * ) );
*****************************************************************************/
vlc_error_t vlc_init( int i_argc, char *ppsz_argv[] )
{
- return vlc_init_r( ( i_vlc == 1 ) ? *pp_vlc : NULL, i_argc, ppsz_argv );
+ return vlc_init_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL, i_argc, ppsz_argv );
}
vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
return VLC_ESTATUS;
}
- fprintf( stderr, COPYRIGHT_MESSAGE "\n" );
-
/* Guess what CPU we have */
p_vlc->i_cpu = CPUCapabilities( p_vlc );
*****************************************************************************/
vlc_error_t vlc_run( void )
{
- return vlc_run_r( ( i_vlc == 1 ) ? *pp_vlc : NULL );
+ return vlc_run_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
}
vlc_error_t vlc_run_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_error_t vlc_add_intf( const char *psz_module, vlc_bool_t b_block )
{
- return vlc_add_intf_r( ( i_vlc == 1 ) ? *pp_vlc : NULL,
+ return vlc_add_intf_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL,
psz_module, b_block );
}
*****************************************************************************/
vlc_error_t vlc_stop( void )
{
- return vlc_stop_r( ( i_vlc == 1 ) ? *pp_vlc : NULL );
+ return vlc_stop_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
}
vlc_error_t vlc_stop_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_error_t vlc_end( void )
{
- return vlc_end_r( ( i_vlc == 1 ) ? *pp_vlc : NULL );
+ return vlc_end_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
}
vlc_error_t vlc_end_r( vlc_t *p_vlc )
*****************************************************************************/
vlc_error_t vlc_destroy( void )
{
- return vlc_destroy_r( ( i_vlc == 1 ) ? *pp_vlc : NULL );
+ return vlc_destroy_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
}
vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
return VLC_SUCCESS;
}
+/*****************************************************************************
+ * vlc_die: ask vlc to die.
+ *****************************************************************************
+ * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
+ * task. It is your duty to call vlc_end and vlc_destroy afterwards.
+ *****************************************************************************/
+vlc_error_t vlc_die( void )
+{
+ return vlc_die_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
+}
+
+vlc_error_t vlc_die_r( vlc_t *p_vlc )
+{
+ if( !p_vlc )
+ {
+ fprintf( stderr, "error: invalid status (!EXIST)\n" );
+ return VLC_ESTATUS;
+ }
+
+ p_vlc->b_die = VLC_TRUE;
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * vlc_status: return the current vlc status.
+ *****************************************************************************
+ * This function returns the current value of p_vlc->i_status.
+ *****************************************************************************/
vlc_status_t vlc_status( void )
{
- return vlc_status_r( ( i_vlc == 1 ) ? *pp_vlc : NULL );
+ return vlc_status_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
}
vlc_status_t vlc_status_r( vlc_t *p_vlc )
return p_vlc->i_status;
}
+/*****************************************************************************
+ * vlc_add_target: adds a target for playing.
+ *****************************************************************************
+ * This function adds psz_target to the current playlist. If a playlist does
+ * not exist, it will create one.
+ *****************************************************************************/
vlc_error_t vlc_add_target( const char *psz_target, int i_mode, int i_pos )
{
- return vlc_add_target_r( ( i_vlc == 1 ) ? *pp_vlc : NULL,
+ return vlc_add_target_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL,
psz_target, i_mode, i_pos );
}
}
#endif
-#ifndef WIN32
-/*****************************************************************************
- * InitSignalHandler: system signal handler initialization
- *****************************************************************************
- * Set the signal handlers. SIGTERM is not intercepted, because we need at
- * at least a method to kill the program when all other methods failed, and
- * when we don't want to use SIGKILL.
- *****************************************************************************/
-static void InitSignalHandler( void )
-{
- /* Termination signals */
- signal( SIGINT, FatalSignalHandler );
- signal( SIGHUP, FatalSignalHandler );
- signal( SIGQUIT, FatalSignalHandler );
-
- /* Other signals */
- signal( SIGALRM, SIG_IGN );
- signal( SIGPIPE, SIG_IGN );
-}
-
-/*****************************************************************************
- * FatalSignalHandler: system signal handler
- *****************************************************************************
- * This function is called when a fatal signal is received by the program.
- * It tries to end the program in a clean way.
- *****************************************************************************/
-static void FatalSignalHandler( int i_signal )
-{
- static mtime_t abort_time = 0;
- static volatile vlc_bool_t b_die = VLC_FALSE;
- int i_index;
-
- /* Once a signal has been trapped, the termination sequence will be
- * armed and following signals will be ignored to avoid sending messages
- * to an interface having been destroyed */
-
- if( !b_die )
- {
- b_die = VLC_TRUE;
- abort_time = mdate();
-
- fprintf( stderr, "signal %d received, terminating libvlc - do it "
- "again in case your process gets stuck\n", i_signal );
-
- /* Try to terminate everything - this is done by requesting the end of
- * all the p_vlc structures */
- for( i_index = 0 ; i_index < i_vlc ; i_index++ )
- {
- /* Acknowledge the signal received */
- pp_vlc[ i_index ]->b_die = VLC_TRUE;
- }
- }
- else if( mdate() > abort_time + 1000000 )
- {
- /* If user asks again 1 second later, die badly */
- signal( SIGINT, SIG_IGN );
- signal( SIGHUP, SIG_IGN );
- signal( SIGQUIT, SIG_IGN );
-
- fprintf( stderr, "user insisted too much, dying badly\n" );
-
- exit( 1 );
- }
-}
-#endif
-
* cpu.c: CPU detection code
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
- * $Id: cpu.c,v 1.4 2002/06/07 14:30:41 sam Exp $
+ * $Id: cpu.c,v 1.5 2002/08/19 11:13:45 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Christophe Massiot <massiot@via.ecp.fr>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static void IllegalSignalHandler( int i_signal );
+static void SigHandler ( int );
+static u32 Capabilities ( vlc_object_t * );
/*****************************************************************************
* Global variables - they're needed for signal handling
#endif
/*****************************************************************************
- * CPUCapabilities: list the processors MMX support and other capabilities
+ * CPUCapabilities: get the CPU capabilities
*****************************************************************************
- * This function is called to list extensions the CPU may have.
+ * This function is a wrapper around Capabilities().
*****************************************************************************/
u32 __CPUCapabilities( vlc_object_t *p_this )
+{
+ u32 i_capabilities;
+
+ vlc_mutex_lock( p_this->p_vlc->p_global_lock );
+ i_capabilities = Capabilities( p_this );
+ vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
+
+ return i_capabilities;
+}
+
+/*****************************************************************************
+ * Capabilities: list the processors MMX support and other capabilities
+ *****************************************************************************
+ * This function is called to list extensions the CPU may have.
+ *****************************************************************************/
+static u32 Capabilities( vlc_object_t *p_this )
{
volatile u32 i_capabilities = CPU_CAPABILITY_NONE;
: "a" ( a ) \
: "cc" );
- i_capabilities |= CPU_CAPABILITY_FPU;
-
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
- signal( SIGILL, IllegalSignalHandler );
+ sighandler_t pf_sigill = signal( SIGILL, SigHandler );
# endif
+ i_capabilities |= CPU_CAPABILITY_FPU;
+
/* test for a 486 CPU */
asm volatile ( "pushl %%ebx\n\t"
"pushfl\n\t"
if( i_eax == i_ebx )
{
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
- signal( SIGILL, NULL );
+ signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
}
if( !i_eax )
{
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
- signal( SIGILL, NULL );
+ signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
}
if( ! (i_edx & 0x00800000) )
{
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
- signal( SIGILL, NULL );
+ signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
}
psz_capability = "SSE";
i_illegal = 0;
- vlc_mutex_lock( p_this->p_vlc->p_global_lock );
if( setjmp( env ) == 0 )
{
/* Test a SSE instruction */
__asm__ __volatile__ ( "xorps %%xmm0,%%xmm0\n" : : );
}
- vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
if( i_illegal == 0 )
{
if( i_eax < 0x80000001 )
{
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
- signal( SIGILL, NULL );
+ signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
}
psz_capability = "3D Now!";
i_illegal = 0;
- vlc_mutex_lock( p_this->p_vlc->p_global_lock );
if( setjmp( env ) == 0 )
{
/* Test a 3D Now! instruction */
__asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : );
}
- vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
if( i_illegal == 0 )
{
}
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
- signal( SIGILL, NULL );
+ signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
#elif defined( __powerpc__ )
- i_capabilities |= CPU_CAPABILITY_FPU;
-
# ifdef CAN_COMPILE_ALTIVEC
- signal( SIGILL, IllegalSignalHandler );
+ sighandler_t pf_sigill = signal( SIGILL, SigHandler );
+
+ i_capabilities |= CPU_CAPABILITY_FPU;
i_illegal = 0;
- vlc_mutex_lock( p_this->p_vlc->p_global_lock );
if( setjmp( env ) == 0 )
{
asm volatile ("mtspr 256, %0\n\t"
:
: "r" (-1));
}
- vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
if( i_illegal == 0 )
{
i_capabilities |= CPU_CAPABILITY_ALTIVEC;
}
- signal( SIGILL, NULL );
+ signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
}
/*****************************************************************************
- * IllegalSignalHandler: system signal handler
+ * SigHandler: system signal handler
*****************************************************************************
* This function is called when an illegal instruction signal is received by
* the program. We use this function to test OS and CPU capabilities
*****************************************************************************/
-static void IllegalSignalHandler( int i_signal )
+static void SigHandler( int i_signal )
{
/* Acknowledge the signal received */
i_illegal = 1;
* vlc.c: the vlc player
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: vlc.c,v 1.8 2002/08/08 00:35:11 sam Exp $
+ * $Id: vlc.c,v 1.9 2002/08/19 11:13:45 sam Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Gildas Bazin <gbazin@netcourrier.com>
+ * Lots of other people, see the libvlc AUTHORS file
*
* 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
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
+
#include <signal.h> /* SIGHUP, SIGINT, SIGKILL */
#include <stdio.h> /* fprintf() */
#include <stdlib.h> /* putenv(), strtol(), */
+#include <signal.h> /* SIGHUP, SIGINT, SIGKILL */
#include <vlc/vlc.h>
+/*****************************************************************************
+ * Local prototypes.
+ *****************************************************************************/
+#ifndef WIN32
+static void SigHandler ( int i_signal );
+#endif
+
/*****************************************************************************
* main: parse command line, start interface and spawn threads
*****************************************************************************/
-int main(int i_argc, char *ppsz_argv[])
+int main( int i_argc, char *ppsz_argv[] )
{
vlc_error_t err;
+ fprintf( stderr, COPYRIGHT_MESSAGE "\n" );
+
#ifdef SYS_LINUX
# ifdef DEBUG
/* Activate malloc checking routines to detect heap corruptions. */
# endif
#endif
- /* Create the vlc structure */
+ /* Create a libvlc structure */
err = vlc_create();
if( err != VLC_SUCCESS )
{
return err;
}
- /* Initialize vlc */
+#ifndef WIN32
+ /* Set the signal handlers. SIGTERM is not intercepted, because we need at
+ * least one method to kill the program when all other methods failed, and
+ * when we don't want to use SIGKILL.
+ * Note that we set the signals after the vlc_create call. */
+ signal( SIGINT, SigHandler );
+ signal( SIGHUP, SigHandler );
+ signal( SIGQUIT, SigHandler );
+
+ /* Other signals */
+ signal( SIGALRM, SIG_IGN );
+ signal( SIGPIPE, SIG_IGN );
+#endif
+
+ /* Initialize libvlc */
err = vlc_init( i_argc, ppsz_argv );
if( err != VLC_SUCCESS )
{
return err;
}
- /* Run vlc, in non-blocking mode */
+ /* Run libvlc, in non-blocking mode */
err = vlc_run();
/* Add background interfaces */
/* Finish all threads */
vlc_end();
- /* Destroy the vlc structure */
+ /* Destroy the libvlc structure */
vlc_destroy();
return err;
}
+#ifndef WIN32
+/*****************************************************************************
+ * SigHandler: system signal handler
+ *****************************************************************************
+ * This function is called when a fatal signal is received by the program.
+ * It tries to end the program in a clean way.
+ *****************************************************************************/
+static void SigHandler( int i_signal )
+{
+ static mtime_t abort_time = 0;
+ static volatile vlc_bool_t b_die = VLC_FALSE;
+
+ /* Once a signal has been trapped, the termination sequence will be
+ * armed and subsequent signals will be ignored to avoid sending signals
+ * to a libvlc structure having been destroyed */
+
+ if( !b_die )
+ {
+ b_die = VLC_TRUE;
+ abort_time = mdate();
+
+ fprintf( stderr, "signal %d received, terminating vlc - do it "
+ "again in case it gets stuck\n", i_signal );
+
+ /* Acknowledge the signal received */
+ vlc_die();
+ }
+ else if( mdate() > abort_time + 1000000 )
+ {
+ /* If user asks again 1 second later, die badly */
+ signal( SIGINT, SIG_DFL );
+ signal( SIGHUP, SIG_DFL );
+ signal( SIGQUIT, SIG_DFL );
+ signal( SIGALRM, SIG_DFL );
+ signal( SIGPIPE, SIG_DFL );
+
+ fprintf( stderr, "user insisted too much, dying badly\n" );
+
+ exit( 1 );
+ }
+}
+#endif
+