diff options
author | Andy Wingo <wingo@pobox.com> | 2011-05-26 18:29:05 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2011-05-26 18:29:05 +0200 |
commit | af4081e9fd1d3bfaf4df906cac990c88e2e7cfa2 (patch) | |
tree | c4b2f552621036085dd4b699c447e8e91b46052f /libguile/scmsigs.c | |
parent | f4e45e91f265429ad1c42d3905dd3c05a0bc0924 (diff) |
leave guile when reading signal pipe
* libguile/scmsigs.c (read_signal_pipe_data, signal_delivery_thread):
Leave guile when reading from the signal pipe. Hopefully that lets GC
know not to wake up this thread.
Diffstat (limited to 'libguile/scmsigs.c')
-rw-r--r-- | libguile/scmsigs.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/libguile/scmsigs.c b/libguile/scmsigs.c index 699a6de83..641d1b3c8 100644 --- a/libguile/scmsigs.c +++ b/libguile/scmsigs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2004, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -148,11 +148,28 @@ take_signal (int signum) #endif } +struct signal_pipe_data +{ + char sigbyte; + ssize_t n; + int err; +}; + +static void* +read_signal_pipe_data (void * data) +{ + struct signal_pipe_data *sdata = data; + + sdata->n = read (signal_pipe[0], &sdata->sigbyte, 1); + sdata->err = errno; + + return NULL; +} + static SCM signal_delivery_thread (void *data) { - int n, sig; - char sigbyte; + int sig; #if HAVE_PTHREAD_SIGMASK /* not on mingw, see notes above */ sigset_t all_sigs; sigfillset (&all_sigs); @@ -161,9 +178,12 @@ signal_delivery_thread (void *data) while (1) { - n = read (signal_pipe[0], &sigbyte, 1); - sig = sigbyte; - if (n == 1 && sig >= 0 && sig < NSIG) + struct signal_pipe_data sigdata; + + scm_without_guile (read_signal_pipe_data, &sigdata); + + sig = sigdata.sigbyte; + if (sigdata.n == 1 && sig >= 0 && sig < NSIG) { SCM h, t; @@ -172,9 +192,9 @@ signal_delivery_thread (void *data) if (scm_is_true (h)) scm_system_async_mark_for_thread (h, t); } - else if (n == 0) + else if (sigdata.n == 0) break; /* the signal pipe was closed. */ - else if (n < 0 && errno != EINTR) + else if (sigdata.n < 0 && sigdata.err != EINTR) perror ("error in signal delivery thread"); } |