From: Tom Hughes (thh_at_cyberscience.com)
Date: Mon Jan 14 2002 - 09:50:50 GMT
In message <200201111853.KAA28214_at_hunter> Rod Armstrong <rod_at_san-jose.tt.slb.com> wrote: > On Linux, wait3() must be used in order to get interrupts. Maybe > someone with a Redhat system could investigate. I've found and solved the wait() problem now. In fact wait() does get interrupts but the problem is that Linux blocks signals while they are being handled and a longjmp() out of the signal handler does not cancel that block, so after the first time SIGIO is blocked and we don't get interrupted. The solution is to use sigsetjmp() and siglongjmp() and set the savesigs flag when calling sigsetjmp() so that the signal context is restored when we jump out of the handler. The following patch does just that, and can be applied in place of my usleep() patch: diff -ur ups-3.37-beta4/ups/ao_ptrace.c ups-wait/ups/ao_ptrace.c --- ups-3.37-beta4/ups/ao_ptrace.c Mon Jan 7 16:54:52 2002 +++ ups-wait/ups/ao_ptrace.c Mon Jan 14 09:45:24 2002 @@ -75,7 +75,11 @@ static int Last_attach_pid; /* Used by 'stop_target()'. */ +#ifdef OS_LINUX +static sigjmp_buf Longjmp_env; +#else static jmp_buf Longjmp_env; +#endif static void stop_target PROTO((void)); @@ -174,7 +178,11 @@ static void stop_target() { +#ifdef OS_LINUX + siglongjmp(Longjmp_env, 1); +#else longjmp(Longjmp_env, 1); +#endif } static int @@ -182,17 +190,17 @@ wait_arg_t *p_status; { int ret; +#ifdef OS_LINUX + if (sigsetjmp(Longjmp_env, 1) == 1) +#else if (setjmp(Longjmp_env) == 1) +#endif return 0; -#ifdef OS_LINUX - ret = wait3(p_status, WNOHANG, NULL); -#else if (get_run_alarm_time() > 0) ret = wait3(p_status, WNOHANG, NULL); else ret = wait(p_status); -#endif return ret; } Tom -- Tom Hughes (thh_at_cyberscience.com) Software Engineer, Cyberscience Corporation http://www.cyberscience.com/
This archive was generated by hypermail 2.1.4 : Wed Feb 13 2002 - 21:51:35 GMT