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 @@
* 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
......@@ -114,6 +114,7 @@ vlc_status_t vlc_status ( void );
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 );
......@@ -129,6 +130,7 @@ vlc_status_t vlc_status_r ( vlc_t * );
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 * );
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* 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>
......@@ -43,7 +43,8 @@
/*****************************************************************************
* 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
......@@ -55,11 +56,27 @@ static char *psz_capability;
#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;
......@@ -112,12 +129,12 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
: "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"
......@@ -138,7 +155,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
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;
}
......@@ -151,7 +168,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
if( !i_eax )
{
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, NULL );
signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
}
......@@ -169,7 +186,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
if( ! (i_edx & 0x00800000) )
{
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, NULL );
signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
}
......@@ -185,13 +202,11 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
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 )
{
......@@ -206,7 +221,7 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
if( i_eax < 0x80000001 )
{
# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
signal( SIGILL, NULL );
signal( SIGILL, pf_sigill );
# endif
return i_capabilities;
}
......@@ -220,13 +235,11 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
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 )
{
......@@ -241,20 +254,19 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
}
# 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"
......@@ -262,14 +274,13 @@ u32 __CPUCapabilities( vlc_object_t *p_this )
:
: "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;
......@@ -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
* 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;
......
......@@ -2,11 +2,12 @@
* 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
......@@ -22,19 +23,30 @@
* 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. */
......@@ -45,14 +57,28 @@ int main(int i_argc, char *ppsz_argv[])
# 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 )
{
......@@ -60,7 +86,7 @@ int main(int i_argc, char *ppsz_argv[])
return err;
}
/* Run vlc, in non-blocking mode */
/* Run libvlc, in non-blocking mode */
err = vlc_run();
/* Add background interfaces */
......@@ -83,9 +109,52 @@ int main(int i_argc, char *ppsz_argv[])
/* 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
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