This is the mail archive of the
java-discuss@sourceware.cygnus.com
mailing list for the Java project.
RE: boehm-gc and sigwait() ?
- To: "'Bryce McKinlay'" <bryce at albatross dot co dot nz>, java-discuss at sourceware dot cygnus dot com
- Subject: RE: boehm-gc and sigwait() ?
- From: "Boehm, Hans" <hboehm at exch dot hpl dot hp dot com>
- Date: Tue, 23 Nov 1999 10:47:27 -0800
What does sigwait do if another signal arrives? Does it allow the handler
to run?
If no, the deadlock is inevitable. The garbage collector counts on being
able to send signals in order to stop other threads. (In the default Linux
configuration, it uses SIGPWR and SIGXCPU, on the assumption that those are
unlikely to be used by the rest of the application.)
Unfortunately, none of this is 100% transparent to C/C++ code, since the
signals can cause premature wakeups of some calls, in addition to problems
such as this. But I don't know of a better way to handle this. (It would
be advantageous to wrap some of the blocking syscalls so that we can avoid
sending signals to threads executing them. But I'm not sure how feasible
that is. There already seem to be problems with the existing read wrapper.)
Hans
-----Original Message-----
From: Bryce McKinlay [mailto:bryce@albatross.co.nz]
Sent: Tuesday, November 23, 1999 3:07 AM
To: java-discuss@sourceware.cygnus.com
Subject: boehm-gc and sigwait() ?
I've been trying to get libgcj to exit more cleanly on Ctrl-C, by
blocking the master thread on sigwait() and calling exit() on SIGINT.
See patch below. This works well, except seem to cause a hang in
boehm-gc when a collection occurs.
Can anyone see a way around this problem?
regards
[ bryce ]
Index: prims.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/prims.cc,v
retrieving revision 1.13
diff -u -r1.13 prims.cc
--- prims.cc 1999/11/05 17:34:32 1.13
+++ prims.cc 1999/11/23 06:26:01
@@ -793,7 +793,8 @@
main_thread->start();
_Jv_ThreadWait ();
- java::lang::Runtime::getRuntime ()->exit (0);
+ // _Jv_ThreadWait returns only on SIGINT (Ctrl-C).
+ ::exit(1);
}
void
Index: posix-threads.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/posix-threads.cc,v
retrieving revision 1.13
diff -u -r1.13 posix-threads.cc
--- posix-threads.cc 1999/11/04 16:45:11 1.13
+++ posix-threads.cc 1999/11/23 06:26:01
@@ -32,6 +32,7 @@
#include <jvm.h>
#include <java/lang/Thread.h>
#include <java/lang/System.h>
+#include <java/lang/Runtime.h>
// This is used to implement thread startup.
struct starter
@@ -53,7 +54,6 @@
// We keep a count of all non-daemon threads which are running. When
// this reaches zero, _Jv_ThreadWait returns.
static pthread_mutex_t daemon_mutex;
-static pthread_cond_t daemon_cond;
static int non_daemon_count;
// The signal to use when interrupting a thread.
@@ -260,7 +260,6 @@
pthread_key_create (&_Jv_ThreadKey, NULL);
pthread_key_create (&_Jv_ThreadDataKey, NULL);
pthread_mutex_init (&daemon_mutex, NULL);
- pthread_cond_init (&daemon_cond, 0);
non_daemon_count = 0;
// Arrange for the interrupt signal to interrupt system calls.
@@ -270,8 +269,7 @@
act.sa_flags = 0;
sigaction (INTR, &act, NULL);
- // Arrange for SIGINT to be blocked to all threads. It is only
- // deliverable to the master thread.
+ // Arrange for SIGINT to be blocked to all threads.
sigset_t mask;
sigemptyset (&mask);
sigaddset (&mask, SIGINT);
@@ -320,7 +318,7 @@
pthread_mutex_lock (&daemon_mutex);
--non_daemon_count;
if (! non_daemon_count)
- pthread_cond_signal (&daemon_cond);
+ java::lang::Runtime::getRuntime ()->exit (0);
pthread_mutex_unlock (&daemon_mutex);
}
@@ -366,16 +364,13 @@
void
_Jv_ThreadWait (void)
{
- // Arrange for SIGINT to be delivered to the master thread.
+ // block the thread, and only return if a SIGINT occurs.
sigset_t mask;
sigemptyset (&mask);
sigaddset (&mask, SIGINT);
- pthread_sigmask (SIG_UNBLOCK, &mask, NULL);
+ int count;
- pthread_mutex_lock (&daemon_mutex);
- if (non_daemon_count)
- pthread_cond_wait (&daemon_cond, &daemon_mutex);
- pthread_mutex_unlock (&daemon_mutex);
+ sigwait(&mask, &count);
}
void