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