Changeset a8f72d056fc842e3d338971ebf2a7511c59855a5

Show
Ignore:
Timestamp:
29/05/08 21:50:35 (5 months ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1212090635 +0300
git-parent:

[0efa83acc9ea7758bceae38f0e0e5453c7239e20]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1212090619 +0300
Message:

Use the signal interface and fix signal handling

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/vlc.c

    r19091cc ra8f72d0  
    4040extern char *FromLocale (const char *); 
    4141 
    42 # include <signal.h> 
    43 # include <time.h> 
    44 # include <pthread.h> 
    45  
    46 static void *SigHandler (void *set); 
     42#include <signal.h> 
     43#include <time.h> 
     44#include <pthread.h> 
     45#include <unistd.h> 
    4746 
    4847/***************************************************************************** 
     
    9392     * We have to handle SIGTERM cleanly because of daemon mode. 
    9493     * Note that we set the signals after the vlc_create call. */ 
    95     static const int exitsigs[] = { SIGINT, SIGHUP, SIGQUIT, SIGTERM }; 
     94    static const int sigs[] = { 
     95        SIGINT, SIGHUP, SIGQUIT, SIGTERM, 
    9696    /* Signals that cause a no-op: 
    97      * - SIGALRM should not happen, but lets stay on the safe side. 
    9897     * - SIGPIPE might happen with sockets and would crash VLC. It MUST be 
    9998     *   blocked by any LibVLC-dependent application, in addition to VLC. 
     
    101100     *   be dequeued to cleanup zombie processes. 
    102101     */ 
    103     static const int dummysigs[] = { SIGALRM, SIGPIPE, SIGCHLD }; 
     102        SIGPIPE, SIGCHLD 
     103    }; 
    104104 
    105105    sigset_t set; 
    106     pthread_t sigth; 
    107  
    108106    sigemptyset (&set); 
    109     for (unsigned i = 0; i < sizeof (exitsigs) / sizeof (exitsigs[0]); i++) 
    110         sigaddset (&set, exitsigs[i]); 
    111     for (unsigned i = 0; i < sizeof (dummysigs) / sizeof (dummysigs[0]); i++) 
    112         sigaddset (&set, dummysigs[i]); 
     107    for (unsigned i = 0; i < sizeof (sigs) / sizeof (sigs[0]); i++) 
     108        sigaddset (&set, sigs[i]); 
    113109 
    114110    /* Block all these signals */ 
    115111    pthread_sigmask (SIG_BLOCK, &set, NULL); 
    116  
    117     for (unsigned i = 0; i < sizeof (dummysigs) / sizeof (dummysigs[0]); i++) 
    118         sigdelset (&set, dummysigs[i]); 
    119  
    120     pthread_create (&sigth, NULL, SigHandler, &set); 
    121112 
    122113    /* Note that FromLocale() can be used before libvlc is initialized */ 
     
    135126    if (vlc != NULL) 
    136127    { 
     128        libvlc_add_intf (vlc, "signals", NULL); 
    137129        libvlc_add_intf (vlc, NULL, &ex); 
    138130        libvlc_wait (vlc); 
     
    145137        LocaleFree (ppsz_argv[i]); 
    146138 
    147     pthread_cancel (sigth); 
    148 # ifdef __APPLE__ 
    149     /* In Mac OS X up to 10.4.8 sigwait (among others) is not a pthread 
    150      * cancellation point, so we throw a dummy quit signal to end 
    151      * sigwait() in the sigth thread */ 
    152     pthread_kill (sigth, SIGQUIT); 
    153 # endif 
    154     pthread_join (sigth, NULL); 
    155  
    156139    return i_ret; 
    157140} 
    158  
    159 /***************************************************************************** 
    160  * SigHandler: system signal handler 
    161  ***************************************************************************** 
    162  * This thread receives all handled signals synchronously. 
    163  * It tries to end the program in a clean way. 
    164  *****************************************************************************/ 
    165 static void *SigHandler (void *data) 
    166 { 
    167     const sigset_t *exitset = (sigset_t *)data; 
    168     sigset_t fullset; 
    169     time_t abort_time = 0; 
    170  
    171     pthread_sigmask (SIG_BLOCK, exitset, &fullset); 
    172  
    173     for (;;) 
    174     { 
    175         int i_signal, state; 
    176         if( sigwait (&fullset, &i_signal) != 0 ) 
    177             continue; 
    178  
    179 #ifdef __APPLE__ 
    180         /* In Mac OS X up to 10.4.8 sigwait (among others) is not a pthread 
    181          * cancellation point */ 
    182         pthread_testcancel(); 
    183 #endif 
    184  
    185         if (!sigismember (exitset, i_signal)) 
    186             continue; /* Ignore "dummy" signals */ 
    187  
    188         /* Once a signal has been trapped, the termination sequence will be 
    189          * armed and subsequent signals will be ignored to avoid sending 
    190          * signals to a libvlc structure having been destroyed */ 
    191  
    192         pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state); 
    193         if (abort_time == 0 || time (NULL) > abort_time) 
    194         { 
    195             time (&abort_time); 
    196             abort_time += 2; 
    197  
    198             fprintf (stderr, "signal %d received, terminating vlc - do it " 
    199                             "again quickly in case it gets stuck\n", i_signal); 
    200             //VLC_Die( 0 ); 
    201         } 
    202         else /* time (NULL) <= abort_time */ 
    203         { 
    204             /* If user asks again more than 2 seconds later, die badly */ 
    205             pthread_sigmask (SIG_UNBLOCK, exitset, NULL); 
    206             fprintf (stderr, "user insisted too much, dying badly\n"); 
    207 #ifdef __APPLE__ 
    208             /* On Mac OS X, use exit(-1) as it doesn't trigger 
    209              * backtrace generation, whereas abort() does. 
    210              * The backtrace generation trigger a Crash Dialog 
    211              * And takes way too much time, which is not what 
    212              * we want. */ 
    213             exit (-1); 
    214 #else 
    215             abort (); 
    216 #endif 
    217         } 
    218         pthread_setcancelstate (state, NULL); 
    219     } 
    220     /* Never reached */ 
    221 }