]> git.sesse.net Git - vlc/commitdiff
* ./src/misc/cpu.c: libvlc now plays nice with SIGILL and restores the
authorSam Hocevar <sam@videolan.org>
Mon, 19 Aug 2002 11:13:45 +0000 (11:13 +0000)
committerSam Hocevar <sam@videolan.org>
Mon, 19 Aug 2002 11:13:45 +0000 (11:13 +0000)
    signal handler to its previous value after use.
  * ./src/libvlc.c: moved signal handling to vlc.c.

include/vlc/vlc.h
src/libvlc.c
src/misc/cpu.c
src/vlc.c

index 9d4264ecc2e47ed92442a2450d7e36335eea709f..7ac8861bd89cba50b5de117d0ee5d844f61f08fe 100644 (file)
@@ -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 * );
index e7672e62788c381db252aee1115b2a2360f18a60..dbf15abbc4d3eb49a2bc262d446ab4a76effab2a 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -37,7 +37,6 @@
 #include <stdio.h>                                              /* sprintf() */
 #include <string.h>                                            /* strerror() */
 #include <stdlib.h>                                                /* free() */
-#include <signal.h>                               /* SIGHUP, SIGINT, SIGKILL */
 
 #include <vlc/vlc.h>
 
@@ -102,11 +101,6 @@ static void Usage         ( vlc_t *, const char *psz_module_name );
 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
@@ -115,12 +109,45 @@ static void ShowConsole   ( void );
  * 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 )
@@ -149,11 +176,6 @@ 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 * ) );
@@ -180,7 +202,7 @@ vlc_t * vlc_create_r( void )
  *****************************************************************************/
 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[] )
@@ -197,8 +219,6 @@ 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 );
 
@@ -511,7 +531,7 @@ vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
  *****************************************************************************/
 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 )
@@ -539,7 +559,7 @@ 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 );
 }
 
@@ -602,7 +622,7 @@ vlc_error_t vlc_add_intf_r( vlc_t *p_vlc, const char *psz_module,
  *****************************************************************************/
 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 )
@@ -679,7 +699,7 @@ 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 )
@@ -737,7 +757,7 @@ 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 )
@@ -802,9 +822,38 @@ 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 )
@@ -817,9 +866,15 @@ 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 );
 }
 
@@ -1177,69 +1232,3 @@ static void ShowConsole( void )
 }
 #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
-
index 4df79dc17189c223fba0162e1e214c7fccdff520..39e9331390933cd958743f2c11fd4218b7eb675a 100644 (file)
@@ -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;
index 5adc5fe8772e6b37d1059734be22d5a972097220..4677528c63caf723b36cc1b9e9c7ed0a05e5ca03 100644 (file)
--- a/src/vlc.c
+++ b/src/vlc.c
@@ -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
  * 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
+