[153] in Pthreads Bugs
Re: sleep / SIGALRM problem in 1_60_beta6
daemon@ATHENA.MIT.EDU (Mon Dec 9 19:32:22 1996
)
Date: Mon, 09 Dec 1996 17:22:50 -0700
From: "Mark M. Evans" <mevans@cti-ltd.com>
To: Tim Hinderliter <kyd@internap.com>
Cc: pthreads-bugs@MIT.EDU
I think I found what caused fd_kern_wait() to block for the entire
hour (instead of waking up due to the SIGALRM). Basically, the
SIGALRM that would move the sleeping thread to the run queue occurs
while pthread_kernel_lock is set, but *before* the critical section in
fd_kern_wait() that sets __fd_kern_wait_timeout.tv_sec to 3600. So,
sig_handler_real() clears __fd_kern_wait_timeout.tv_sec "too soon."
I've worked around this by checking sig_to_process in the critical
section to determine if we are truly idle. To do this I had to make
sig_to_process publicly available.
Here are the diffs (relative to the pthreads/pthreads directory):
diff -c -r1.2 -r1.3
*** signal.c 1996/11/20 05:09:50 1.2
--- signal.c 1996/12/09 23:14:52 1.3
***************
*** 65,71 ****
*/
static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
! static sig_atomic_t sig_to_process = 0;
/* static volatile sigset_t sig_to_process; */
static volatile int sig_count = 0;
--- 65,71 ----
*/
static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, };
! sig_atomic_t sig_to_process = 0;
/* static volatile sigset_t sig_to_process; */
static volatile int sig_count = 0;
*** fd_kern.c 1996/12/03 04:14:59 1.6
--- fd_kern.c 1996/12/09 23:14:51 1.7
***************
*** 215,221 ****
* Called when there is no active thread to run.
*/
extern struct timeval __fd_kern_wait_timeout;
!
void fd_kern_wait()
{
fd_set fd_set_read, fd_set_write, fd_set_except;
--- 215,221 ----
* Called when there is no active thread to run.
*/
extern struct timeval __fd_kern_wait_timeout;
! extern volatile sig_atomic_t sig_to_process;
void fd_kern_wait()
{
fd_set fd_set_read, fd_set_write, fd_set_except;
***************
*** 254,260 ****
machdep_unset_thread_timer(NULL);
__fd_kern_wait_timeout.tv_usec = 0;
! __fd_kern_wait_timeout.tv_sec = 3600;
machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);
--- 254,260 ----
machdep_unset_thread_timer(NULL);
__fd_kern_wait_timeout.tv_usec = 0;
! __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600;
machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset);