Changeset a8f72d056fc842e3d338971ebf2a7511c59855a5
- Timestamp:
- 29/05/08 21:50:35 (5 months ago)
- git-parent:
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
src/vlc.c
r19091cc ra8f72d0 40 40 extern char *FromLocale (const char *); 41 41 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> 47 46 48 47 /***************************************************************************** … … 93 92 * We have to handle SIGTERM cleanly because of daemon mode. 94 93 * 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, 96 96 /* Signals that cause a no-op: 97 * - SIGALRM should not happen, but lets stay on the safe side.98 97 * - SIGPIPE might happen with sockets and would crash VLC. It MUST be 99 98 * blocked by any LibVLC-dependent application, in addition to VLC. … … 101 100 * be dequeued to cleanup zombie processes. 102 101 */ 103 static const int dummysigs[] = { SIGALRM, SIGPIPE, SIGCHLD }; 102 SIGPIPE, SIGCHLD 103 }; 104 104 105 105 sigset_t set; 106 pthread_t sigth;107 108 106 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]); 113 109 114 110 /* Block all these signals */ 115 111 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);121 112 122 113 /* Note that FromLocale() can be used before libvlc is initialized */ … … 135 126 if (vlc != NULL) 136 127 { 128 libvlc_add_intf (vlc, "signals", NULL); 137 129 libvlc_add_intf (vlc, NULL, &ex); 138 130 libvlc_wait (vlc); … … 145 137 LocaleFree (ppsz_argv[i]); 146 138 147 pthread_cancel (sigth);148 # ifdef __APPLE__149 /* In Mac OS X up to 10.4.8 sigwait (among others) is not a pthread150 * cancellation point, so we throw a dummy quit signal to end151 * sigwait() in the sigth thread */152 pthread_kill (sigth, SIGQUIT);153 # endif154 pthread_join (sigth, NULL);155 156 139 return i_ret; 157 140 } 158 159 /*****************************************************************************160 * SigHandler: system signal handler161 *****************************************************************************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 pthread181 * cancellation point */182 pthread_testcancel();183 #endif184 185 if (!sigismember (exitset, i_signal))186 continue; /* Ignore "dummy" signals */187 188 /* Once a signal has been trapped, the termination sequence will be189 * armed and subsequent signals will be ignored to avoid sending190 * 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 trigger209 * backtrace generation, whereas abort() does.210 * The backtrace generation trigger a Crash Dialog211 * And takes way too much time, which is not what212 * we want. */213 exit (-1);214 #else215 abort ();216 #endif217 }218 pthread_setcancelstate (state, NULL);219 }220 /* Never reached */221 }
