tools/gst-launch.c: Fix deadlocks in signal.h-type signal handlers by not calling forbidden functions, including gst_...

Original commit message from CVS:
* tools/gst-launch.c: (idle_func), (fault_handler_sighandler),
(fault_handler_sigaction), (fault_spin),
(sigint_handler_sighandler), (play_handler), (main): Fix deadlocks
in signal.h-type signal handlers by not calling forbidden functions,
including gst_element_set_state().
This commit is contained in:
David Schleef 2005-01-06 03:31:17 +00:00
parent e76390343f
commit d84d463b1d
2 changed files with 37 additions and 18 deletions

View file

@ -1,3 +1,11 @@
2005-01-05 David Schleef <ds@schleef.org>
* tools/gst-launch.c: (idle_func), (fault_handler_sighandler),
(fault_handler_sigaction), (fault_spin),
(sigint_handler_sighandler), (play_handler), (main): Fix deadlocks
in signal.h-type signal handlers by not calling forbidden functions,
including gst_element_set_state().
2005-01-05 David Schleef <ds@schleef.org> 2005-01-05 David Schleef <ds@schleef.org>
* gst/gstvalue.h: Mark _gst_reserved[] as private * gst/gstvalue.h: Mark _gst_reserved[] as private

View file

@ -65,8 +65,10 @@ static guint64 min = G_MAXINT64;
static guint64 max = 0; static guint64 max = 0;
static GstClock *s_clock; static GstClock *s_clock;
static GstElement *pipeline; static GstElement *pipeline;
gboolean caught_intr = FALSE; static gboolean caught_intr = FALSE;
gboolean caught_error = FALSE; static gboolean caught_error = FALSE;
static gboolean need_new_state = FALSE;
static GstElementState new_state;
gboolean gboolean
idle_func (gpointer data) idle_func (gpointer data)
@ -86,6 +88,11 @@ idle_func (gpointer data)
min = MIN (min, diff); min = MIN (min, diff);
max = MAX (max, diff); max = MAX (max, diff);
if (need_new_state) {
gst_element_set_state (pipeline, new_state);
need_new_state = FALSE;
}
if (!busy || caught_intr || caught_error || if (!busy || caught_intr || caught_error ||
(max_iterations > 0 && iterations >= max_iterations)) { (max_iterations > 0 && iterations >= max_iterations)) {
char *s_iterations; char *s_iterations;
@ -195,15 +202,17 @@ fault_handler_sighandler (int signum)
{ {
fault_restore (); fault_restore ();
/* printf is used instead of g_print(), since it's less likely to
* deadlock */
switch (signum) { switch (signum) {
case SIGSEGV: case SIGSEGV:
g_print ("Caught SIGSEGV\n"); printf ("Caught SIGSEGV\n");
break; break;
case SIGQUIT: case SIGQUIT:
g_print ("Caught SIGQUIT\n"); printf ("Caught SIGQUIT\n");
break; break;
default: default:
g_print ("signo: %d\n", signum); printf ("signo: %d\n", signum);
break; break;
} }
@ -217,17 +226,19 @@ fault_handler_sigaction (int signum, siginfo_t * si, void *misc)
{ {
fault_restore (); fault_restore ();
/* printf is used instead of g_print(), since it's less likely to
* deadlock */
switch (si->si_signo) { switch (si->si_signo) {
case SIGSEGV: case SIGSEGV:
g_print ("Caught SIGSEGV accessing address %p\n", si->si_addr); printf ("Caught SIGSEGV accessing address %p\n", si->si_addr);
break; break;
case SIGQUIT: case SIGQUIT:
g_print ("Caught SIGQUIT\n"); printf ("Caught SIGQUIT\n");
break; break;
default: default:
g_print ("signo: %d\n", si->si_signo); printf ("signo: %d\n", si->si_signo);
g_print ("errno: %d\n", si->si_errno); printf ("errno: %d\n", si->si_errno);
g_print ("code: %d\n", si->si_code); printf ("code: %d\n", si->si_code);
break; break;
} }
@ -246,7 +257,7 @@ fault_spin (void)
wait (NULL); wait (NULL);
/* FIXME how do we know if we were run by libtool? */ /* FIXME how do we know if we were run by libtool? */
g_print ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, " printf ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, "
"Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ()); "Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ());
while (spinning) while (spinning)
g_usleep (1000000); g_usleep (1000000);
@ -330,8 +341,6 @@ error_cb (GObject * object, GstObject * source, GError * error, gchar * debug)
static void static void
sigint_handler_sighandler (int signum) sigint_handler_sighandler (int signum)
{ {
g_print ("Caught interrupt.\n");
sigint_restore (); sigint_restore ();
caught_intr = TRUE; caught_intr = TRUE;
@ -364,12 +373,12 @@ play_handler (int signum)
{ {
switch (signum) { switch (signum) {
case SIGUSR1: case SIGUSR1:
g_print ("Caught SIGUSR1 - Play request.\n"); new_state = GST_STATE_PLAYING;
gst_element_set_state (pipeline, GST_STATE_PLAYING); need_new_state = TRUE;
break; break;
case SIGUSR2: case SIGUSR2:
g_print ("Caught SIGUSR2 - Stop request.\n"); new_state = GST_STATE_NULL;
gst_element_set_state (pipeline, GST_STATE_NULL); need_new_state = TRUE;
break; break;
} }
} }
@ -545,8 +554,10 @@ main (int argc, char *argv[])
gst_element_wait_state_change (pipeline); gst_element_wait_state_change (pipeline);
g_print ("got the state change.\n"); g_print ("got the state change.\n");
} }
if (caught_intr) if (caught_intr) {
g_print ("Caught interrupt.\n");
res = 2; res = 2;
}
if (caught_error) if (caught_error)
res = 3; res = 3;