Commit 2fa6c9ce authored by Sam Hocevar's avatar Sam Hocevar

* ./src/misc/cpu.c: libvlc now plays nice with SIGILL and restores the

    signal handler to its previous value after use.
  * ./src/libvlc.c: moved signal handling to vlc.c.
parent 9c669a9f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vlc.h: global header for vlc * vlc.h: global header for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -114,6 +114,7 @@ vlc_status_t vlc_status ( void ); ...@@ -114,6 +114,7 @@ vlc_status_t vlc_status ( void );
vlc_error_t vlc_create ( void ); vlc_error_t vlc_create ( void );
vlc_error_t vlc_init ( int, char *[] ); vlc_error_t vlc_init ( int, char *[] );
vlc_error_t vlc_run ( void ); vlc_error_t vlc_run ( void );
vlc_error_t vlc_die ( void );
vlc_error_t vlc_stop ( void ); vlc_error_t vlc_stop ( void );
vlc_error_t vlc_end ( void ); vlc_error_t vlc_end ( void );
vlc_error_t vlc_destroy ( void ); vlc_error_t vlc_destroy ( void );
...@@ -129,6 +130,7 @@ vlc_status_t vlc_status_r ( vlc_t * ); ...@@ -129,6 +130,7 @@ vlc_status_t vlc_status_r ( vlc_t * );
vlc_t * vlc_create_r ( void ); vlc_t * vlc_create_r ( void );
vlc_error_t vlc_init_r ( vlc_t *, int, char *[] ); vlc_error_t vlc_init_r ( vlc_t *, int, char *[] );
vlc_error_t vlc_run_r ( vlc_t * ); 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_stop_r ( vlc_t * );
vlc_error_t vlc_end_r ( vlc_t * ); vlc_error_t vlc_end_r ( vlc_t * );
vlc_error_t vlc_destroy_r ( vlc_t * ); vlc_error_t vlc_destroy_r ( vlc_t * );
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* cpu.c: CPU detection code * cpu.c: CPU detection code
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2002 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -43,7 +43,8 @@ ...@@ -43,7 +43,8 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * 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 * Global variables - they're needed for signal handling
...@@ -55,11 +56,27 @@ static char *psz_capability; ...@@ -55,11 +56,27 @@ static char *psz_capability;
#endif #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 __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; volatile u32 i_capabilities = CPU_CAPABILITY_NONE;
...@@ -112,12 +129,12 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -112,12 +129,12 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
: "a" ( a ) \ : "a" ( a ) \
: "cc" ); : "cc" );
i_capabilities |= CPU_CAPABILITY_FPU;
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, IllegalSignalHandler ); sighandler_t pf_sigill = signal( SIGILL, SigHandler );
# endif # endif
i_capabilities |= CPU_CAPABILITY_FPU;
/* test for a 486 CPU */ /* test for a 486 CPU */
asm volatile ( "pushl %%ebx\n\t" asm volatile ( "pushl %%ebx\n\t"
"pushfl\n\t" "pushfl\n\t"
...@@ -138,7 +155,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -138,7 +155,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
if( i_eax == i_ebx ) if( i_eax == i_ebx )
{ {
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, NULL ); signal( SIGILL, pf_sigill );
# endif # endif
return i_capabilities; return i_capabilities;
} }
...@@ -151,7 +168,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -151,7 +168,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
if( !i_eax ) if( !i_eax )
{ {
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, NULL ); signal( SIGILL, pf_sigill );
# endif # endif
return i_capabilities; return i_capabilities;
} }
...@@ -169,7 +186,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -169,7 +186,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
if( ! (i_edx & 0x00800000) ) if( ! (i_edx & 0x00800000) )
{ {
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, NULL ); signal( SIGILL, pf_sigill );
# endif # endif
return i_capabilities; return i_capabilities;
} }
...@@ -185,13 +202,11 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -185,13 +202,11 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
psz_capability = "SSE"; psz_capability = "SSE";
i_illegal = 0; i_illegal = 0;
vlc_mutex_lock( p_this->p_vlc->p_global_lock );
if( setjmp( env ) == 0 ) if( setjmp( env ) == 0 )
{ {
/* Test a SSE instruction */ /* Test a SSE instruction */
__asm__ __volatile__ ( "xorps %%xmm0,%%xmm0\n" : : ); __asm__ __volatile__ ( "xorps %%xmm0,%%xmm0\n" : : );
} }
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
if( i_illegal == 0 ) if( i_illegal == 0 )
{ {
...@@ -206,7 +221,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -206,7 +221,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
if( i_eax < 0x80000001 ) if( i_eax < 0x80000001 )
{ {
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, NULL ); signal( SIGILL, pf_sigill );
# endif # endif
return i_capabilities; return i_capabilities;
} }
...@@ -220,13 +235,11 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -220,13 +235,11 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
psz_capability = "3D Now!"; psz_capability = "3D Now!";
i_illegal = 0; i_illegal = 0;
vlc_mutex_lock( p_this->p_vlc->p_global_lock );
if( setjmp( env ) == 0 ) if( setjmp( env ) == 0 )
{ {
/* Test a 3D Now! instruction */ /* Test a 3D Now! instruction */
__asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : ); __asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : );
} }
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
if( i_illegal == 0 ) if( i_illegal == 0 )
{ {
...@@ -241,20 +254,19 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -241,20 +254,19 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
} }
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, NULL ); signal( SIGILL, pf_sigill );
# endif # endif
return i_capabilities; return i_capabilities;
#elif defined( __powerpc__ ) #elif defined( __powerpc__ )
i_capabilities |= CPU_CAPABILITY_FPU;
# ifdef CAN_COMPILE_ALTIVEC # ifdef CAN_COMPILE_ALTIVEC
signal( SIGILL, IllegalSignalHandler ); sighandler_t pf_sigill = signal( SIGILL, SigHandler );
i_capabilities |= CPU_CAPABILITY_FPU;
i_illegal = 0; i_illegal = 0;
vlc_mutex_lock( p_this->p_vlc->p_global_lock );
if( setjmp( env ) == 0 ) if( setjmp( env ) == 0 )
{ {
asm volatile ("mtspr 256, %0\n\t" asm volatile ("mtspr 256, %0\n\t"
...@@ -262,14 +274,13 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -262,14 +274,13 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
: :
: "r" (-1)); : "r" (-1));
} }
vlc_mutex_unlock( p_this->p_vlc->p_global_lock );
if( i_illegal == 0 ) if( i_illegal == 0 )
{ {
i_capabilities |= CPU_CAPABILITY_ALTIVEC; i_capabilities |= CPU_CAPABILITY_ALTIVEC;
} }
signal( SIGILL, NULL ); signal( SIGILL, pf_sigill );
# endif # endif
return i_capabilities; return i_capabilities;
...@@ -287,12 +298,12 @@ u32 __CPUCapabilities( vlc_object_t *p_this ) ...@@ -287,12 +298,12 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
} }
/***************************************************************************** /*****************************************************************************
* IllegalSignalHandler: system signal handler * SigHandler: system signal handler
***************************************************************************** *****************************************************************************
* This function is called when an illegal instruction signal is received by * This function is called when an illegal instruction signal is received by
* the program. We use this function to test OS and CPU capabilities * 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 */ /* Acknowledge the signal received */
i_illegal = 1; i_illegal = 1;
......
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
* vlc.c: the vlc player * vlc.c: the vlc player
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
* Gildas Bazin <gbazin@netcourrier.com> * 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -22,19 +23,30 @@ ...@@ -22,19 +23,30 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
#include <signal.h> /* SIGHUP, SIGINT, SIGKILL */ #include <signal.h> /* SIGHUP, SIGINT, SIGKILL */
#include <stdio.h> /* fprintf() */ #include <stdio.h> /* fprintf() */
#include <stdlib.h> /* putenv(), strtol(), */ #include <stdlib.h> /* putenv(), strtol(), */
#include <signal.h> /* SIGHUP, SIGINT, SIGKILL */
#include <vlc/vlc.h> #include <vlc/vlc.h>
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
#ifndef WIN32
static void SigHandler ( int i_signal );
#endif
/***************************************************************************** /*****************************************************************************
* main: parse command line, start interface and spawn threads * 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; vlc_error_t err;
fprintf( stderr, COPYRIGHT_MESSAGE "\n" );
#ifdef SYS_LINUX #ifdef SYS_LINUX
# ifdef DEBUG # ifdef DEBUG
/* Activate malloc checking routines to detect heap corruptions. */ /* Activate malloc checking routines to detect heap corruptions. */
...@@ -45,14 +57,28 @@ int main(int i_argc, char *ppsz_argv[]) ...@@ -45,14 +57,28 @@ int main(int i_argc, char *ppsz_argv[])
# endif # endif
#endif #endif
/* Create the vlc structure */ /* Create a libvlc structure */
err = vlc_create(); err = vlc_create();
if( err != VLC_SUCCESS ) if( err != VLC_SUCCESS )
{ {
return err; 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 ); err = vlc_init( i_argc, ppsz_argv );
if( err != VLC_SUCCESS ) if( err != VLC_SUCCESS )
{ {
...@@ -60,7 +86,7 @@ int main(int i_argc, char *ppsz_argv[]) ...@@ -60,7 +86,7 @@ int main(int i_argc, char *ppsz_argv[])
return err; return err;
} }
/* Run vlc, in non-blocking mode */ /* Run libvlc, in non-blocking mode */
err = vlc_run(); err = vlc_run();
/* Add background interfaces */ /* Add background interfaces */
...@@ -83,9 +109,52 @@ int main(int i_argc, char *ppsz_argv[]) ...@@ -83,9 +109,52 @@ int main(int i_argc, char *ppsz_argv[])
/* Finish all threads */ /* Finish all threads */
vlc_end(); vlc_end();
/* Destroy the vlc structure */ /* Destroy the libvlc structure */
vlc_destroy(); vlc_destroy();
return err; 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment