Google Groupes n'accepte plus les nouveaux posts ni abonnements Usenet. Les contenus de l'historique resteront visibles.

[Example] Catching SIGINT in a Java application under UNIX

563 vues
Accéder directement au premier message non lu

Mark Gritter

non lue,
25 nov. 1997, 03:00:0025/11/1997
à

The following example shows how to catch SIGINT (Ctrl-C) in a Java
application. As I (and others) have discovered, calling Java methods
directly from a signal handler tends to crash the JVM. The following
code shows one method of working around this, which should be adaptable
to catching other UNIX signals.

I've only tried it on Solaris, using the Sun JVM with green threads.
I'm rather surprised that it works, since I didn't use a non-blocking
read.

/* CatchSignal.java -- compile and run through javah! */
public class CatchSignal implements Runnable {
static {
System.loadLibrary("CatchSignal");
}

public native static void setControlCHandler();

public static void callback() {
System.err.println("Control-C hit!");
}

public void run() {
setControlCHandler(); // never returns
}

public static void main(String[] args) {
Thread t = new Thread(new CatchSignal());
t.setDaemon(true); // allow program to end even though
// signal-handling thread doesn't
t.setPriority(Thread.MAX_PRIORITY); // ensure signals are handled promptly
t.start();

// Do some lengthy computation...
int i;
for (i = 0; i < 5000000; i++) {
if (i % 100000 == 0) System.out.print(i / 100000 + " ");
}
System.out.println("");
}
}

/* CatchSignal.c -- compile as shared library libCatchSignal.so */
/* See the java tutorial for details on compiling native code libraries. */
#include "CatchSignal.h"
#include <signal.h>
#include <unistd.h>

int pipefd;

void ctrl_c_handler() {
int foo = SIGINT;
write(pipefd, &foo, sizeof(int));
signal(SIGINT, ctrl_c_handler);
}

JNIEXPORT void JNICALL
Java_CatchSignal_setControlCHandler (JNIEnv *env, jclass cls) {
int filedes[2], sigfd, s;
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "callback", "()V");

pipe(filedes);
pipefd = filedes[0];
sigfd = filedes[1];

signal(SIGINT, ctrl_c_handler);

while (1) {
read(sigfd, &s, sizeof(int));
(*env)->CallStaticVoidMethod(env, cls, mid);
}
}

--
Mark Gritter <mgri...@cs.stanford.edu> http://www.stanford.edu/~mgritter/
/* "Perhaps there is no regularity to be discerned." */
/* "Oh, you and your constant rumblings about chaos! I'll hear */
/* none of that, thank you." -- The Tortise and Achilles */

0 nouveau message