You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/09/17 18:32:40 UTC

svn commit: r816267 - in /commons/sandbox/runtime/trunk/src: main/java/org/apache/commons/runtime/SignalAction.java main/native/os/unix/main.c main/native/os/unix/signals.c main/native/shared/sigaction.c test/org/apache/commons/runtime/TestSignal.java

Author: mturk
Date: Thu Sep 17 16:32:40 2009
New Revision: 816267

URL: http://svn.apache.org/viewvc?rev=816267&view=rev
Log:
Save signals on init so we can safely call SIG_DFL

Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SignalAction.java
    commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c
    commons/sandbox/runtime/trunk/src/main/native/os/unix/signals.c
    commons/sandbox/runtime/trunk/src/main/native/shared/sigaction.c
    commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSignal.java

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SignalAction.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SignalAction.java?rev=816267&r1=816266&r2=816267&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SignalAction.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/SignalAction.java Thu Sep 17 16:32:40 2009
@@ -92,7 +92,9 @@
     private static final int SIG_ERR   = 2;
     private static final int SIG_SET   = 3;
 
+    private static native void init0();
     static {
+        init0();
         sa.put(Signal.UNKNOWN, new SignalHandlerCallback(ERR));
 
     }

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c?rev=816267&r1=816266&r2=816267&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/main.c Thu Sep 17 16:32:40 2009
@@ -71,12 +71,14 @@
 static int initialized = 0;
 ACR_DECLARE(int) ACR_Initialize(JavaVM *vm)
 {
-
+    int rc;
 
     acr_pvm = vm;
     if (initialized++)
         return 0;
 
+    if ((rc = acr_SignalsInit()))
+        return rc;
     if (pthread_key_create(&acr_thread_key, acr_thread_key_destructor))
         return ACR_GET_OS_ERROR();
 

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/signals.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/signals.c?rev=816267&r1=816266&r2=816267&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/signals.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/signals.c Thu Sep 17 16:32:40 2009
@@ -26,10 +26,41 @@
 #include "acr_crypto.h"
 #include "acr_signals.h"
 
+/* Since we rember signals during init phase
+ * daemon tools must enure to setup the
+ * signals befre calling init.
+ */
+static struct sigaction *_signalset[ACR_NUMSIG];
 int acr_SignalsInit()
 {
-    int rc = 0;
-
+    int i, rc = 0;
+    for (i = 0; i < ACR_NUMSIG; i++) {
+        _signalset[i] = s_calloc(struct sigaction, 1);
+        if (_signalset[i] == NULL)
+            return ACR_GET_OS_ERROR();
+    }
+    for (i = 0; i < ACR_NUMSIG; i++) {
+        struct sigaction act;
+        act.sa_handler = SIG_DFL;
+        sigemptyset(&act.sa_mask);
+        act.sa_flags = 0;
+#ifdef SA_INTERRUPT             /* SunOS */
+        act.sa_flags |= SA_INTERRUPT;
+#endif
+        if (sigaction(i, &act, _signalset[i]) == 0) {
+            /* Restore the original saved sigaction.
+             * ###: Perhaps there is a smarter for getting the
+             * original signal handlers.
+             */
+            sigaction(i, _signalset[i], &act);
+        }
+        else {
+            /* Those are for SIGKILL and SIGSTOP
+             * which cannot be caught or ignored.
+             */
+            _signalset[i]->sa_handler = SIG_ERR;
+        }
+    }
     return rc;
 }
 
@@ -69,8 +100,13 @@
 
 ACR_DECLARE(acr_sigfunc_t *) ACR_Signal(int signo, acr_sigfunc_t *func)
 {
+    int rc;
     struct sigaction act, oact;
 
+    if (signo < 1 || signo > ACR_NUMSIG) {
+        errno = EINVAL;
+        return SIG_ERR;
+    }
     act.sa_handler = func;
     sigemptyset(&act.sa_mask);
     act.sa_flags = 0;
@@ -86,7 +122,15 @@
         act.sa_handler = avoid_zombies;
     }
 #endif
-    if (sigaction(signo, &act, &oact) < 0)
+    if (func == SIG_DFL) {
+        if (_signalset[signo]->sa_handler != SIG_ERR)
+            rc = sigaction(signo, _signalset[signo], &oact);
+        else
+            rc = EACCES;
+    }
+    else
+        rc = sigaction(signo, &act, &oact);
+    if (rc < 0)
         return SIG_ERR;
     return oact.sa_handler;
 }

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/sigaction.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/sigaction.c?rev=816267&r1=816266&r2=816267&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/sigaction.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/sigaction.c Thu Sep 17 16:32:40 2009
@@ -221,16 +221,17 @@
     if (signo > 0 && signo < ACR_NUMSIG) {
         acr_callback_t *cb = _callbacks[signo];
         if (cb) {
-            int rc;
-            int rv;
-            int sc;
-            int sn  = 0;
+            int rc, rv, sc, sn  = 0;
             for (sc = 0; sc < ACR_COUNTOF(_sig_translate); sc++) {
                 if (_sig_translate[sc] == signo) {
                     sn = sc;
                     break;
                 }
             }
+            /* Passing NULL for JNIEnv will cause to attach it
+             * either to the current thread or attach a native
+             * thread as daemon.
+             */
             rc = ACR_CallbackRun(NULL, cb, NULL, sn, &rv);
             if (rc || rv) {
                 /* TODO: Restore the callback
@@ -240,32 +241,30 @@
     }
 }
 
+ACR_JNI_EXPORT_DECLARE(void, SignalAction, init0)(ACR_JNISTDARGS)
+{
+    memset(_callbacks, 0, ACR_NUMSIG * sizeof(acr_callback_t *));
+}
+
 ACR_JNI_EXPORT_DECLARE(jint, SignalAction, raise0)(ACR_JNISTDARGS, jint sig)
 {
-    int signum = 0;
-    if (sig > 0 && sig < ACR_NUMSIG)
-        signum = _sig_translate[sig];
-    else
-        return ACR_EINVAL;
-    return ACR_RaiseSignal(NULL, signum, -1);
+    if (_sig_translate[sig] == 0)
+        return ACR_ENOTIMPL;
+    return ACR_RaiseSignal(NULL, _sig_translate[sig], -1);
 }
 
 ACR_JNI_EXPORT_DECLARE(jint, SignalAction, signal0)(ACR_JNISTDARGS, jint sig,
                                                     jint mode, jobject callback)
 {
     acr_sigfunc_t *handler;
-    int signum = 0;
+    int signum = _sig_translate[sig];
 
-    if (sig > 0 && sig < ACR_NUMSIG)
-        signum = _sig_translate[sig];
-    else
-        return ACR_EINVAL;
-    if (signum < 0)
+    if (signum == 0)
         return ACR_ENOTIMPL;
     if (_callbacks[signum]) {
         ACR_CallbackFree(_E, _callbacks[signum]);
+        _callbacks[signum] = NULL;
     }
-    _callbacks[signum] = NULL;
     switch (mode) {
         case ACR_JSIG_IGN:
             handler = SIG_IGN;
@@ -275,7 +274,8 @@
         break;
         case ACR_JSIG_SET:
             handler = _sig_handler;
-            _callbacks[signum] = ACR_CallbackAttach(_E, callback, NULL, 0, ACR_CALLBACK_SYNC, NULL);
+            _callbacks[signum] = ACR_CallbackAttach(_E, callback, NULL, 0,
+                                                    ACR_CALLBACK_SYNC, NULL);
             if (_callbacks[signum] == NULL)
                 return ACR_GET_OS_ERROR();
         break;

Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSignal.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSignal.java?rev=816267&r1=816266&r2=816267&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSignal.java (original)
+++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSignal.java Thu Sep 17 16:32:40 2009
@@ -47,7 +47,9 @@
         public void handler(Signal signo)
             throws Exception
         {
-            counter++;
+            synchronized(TestSignal.class) {
+                counter++;
+            }
             System.out.println("Received signal(" + signo + ") in " +
                                Thread.currentThread().getName());
         }
@@ -62,7 +64,7 @@
         System.out.println("Handler initialized in " + Thread.currentThread().getName());
         for (int i = 0; i < 2; i++) {
             try {
-                Thread.sleep(1000);
+                Thread.sleep(100);
             } catch (Throwable e) {
                 // Ignore
             }
@@ -86,7 +88,7 @@
             System.out.println("Handler initialized in " + Thread.currentThread().getName());
             for (int i = 0; i < 2; i++) {
                 try {
-                    Thread.sleep(500);
+                    Thread.sleep(100);
                 } catch (Throwable e) {
                 // Ignore
                 }