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 2011/06/02 18:29:44 UTC

svn commit: r1130635 - in /commons/proper/daemon/trunk/src: java/org/apache/commons/daemon/ java/org/apache/commons/daemon/support/ native/unix/native/ test/org/apache/commons/daemon/

Author: mturk
Date: Thu Jun  2 16:29:44 2011
New Revision: 1130635

URL: http://svn.apache.org/viewvc?rev=1130635&view=rev
Log:
DAEMON-204 Implement modified version of the Nick's patch by making sure his code is usable not ong for softReload. It is up to the user to decide what should be performed on SIGUSR2

Added:
    commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/DaemonUserSignal.java   (with props)
Modified:
    commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/support/DaemonLoader.java
    commons/proper/daemon/trunk/src/native/unix/native/java.c
    commons/proper/daemon/trunk/src/native/unix/native/java.h
    commons/proper/daemon/trunk/src/native/unix/native/jsvc-unix.c
    commons/proper/daemon/trunk/src/test/org/apache/commons/daemon/SimpleDaemon.java

Added: commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/DaemonUserSignal.java
URL: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/DaemonUserSignal.java?rev=1130635&view=auto
==============================================================================
--- commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/DaemonUserSignal.java (added)
+++ commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/DaemonUserSignal.java Thu Jun  2 16:29:44 2011
@@ -0,0 +1,39 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.commons.daemon;
+
+/**
+ * This interface tags a Daemon as supporting some kind of
+ * signaling method that allows the java application to
+ * perform a custom action.
+ * <p>
+ * User must implement a signal method that will be called from
+ * native upon receiving {@code SIGUSR2} signal from the operating system.
+ * </p>
+ * @author Nick Griffiths <ni...@gmail.com>
+ * @author Mladen Turk <mt...@apache.org>
+ */
+public interface DaemonUserSignal
+{
+
+    /**
+     * Perform a custom action on received user signal.
+     */
+    void signal();
+
+}

Propchange: commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/DaemonUserSignal.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/support/DaemonLoader.java
URL: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/support/DaemonLoader.java?rev=1130635&r1=1130634&r2=1130635&view=diff
==============================================================================
--- commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/support/DaemonLoader.java (original)
+++ commons/proper/daemon/trunk/src/java/org/apache/commons/daemon/support/DaemonLoader.java Thu Jun  2 16:29:44 2011
@@ -40,6 +40,7 @@ public final class DaemonLoader
     private static Method start     = null; //@GuardedBy("this")
     private static Method stop      = null; //@GuardedBy("this")
     private static Method destroy   = null; //@GuardedBy("this")
+    private static Method signal    = null; //@GuardedBy("this")
 
     public static void version()
     {
@@ -96,6 +97,23 @@ public final class DaemonLoader
         return true;
     }
 
+    public static boolean signal()
+    {
+        try {
+            if (signal != null) {
+                signal.invoke(daemon, new Object[0]);
+                return true;
+            }
+            else {
+                System.out.println("Daemon doesn't support signaling");
+            }
+        } catch (Throwable ex) {
+            System.err.println("Cannot send signal: " + ex);
+            ex.printStackTrace(System.err);
+        }
+        return false;
+    }
+
     public static boolean load(String className, String args[])
     {
         try {
@@ -162,6 +180,12 @@ public final class DaemonLoader
             stop    = c.getMethod("stop", myclass);
             destroy = c.getMethod("destroy", myclass);
 
+            try {
+                signal = c.getMethod("signal", myclass);
+            } catch (NoSuchMethodException e) {
+                // Signaling will be disabled.
+            }
+
             /* Create a new instance of the daemon */
             daemon = c.newInstance();
 

Modified: commons/proper/daemon/trunk/src/native/unix/native/java.c
URL: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/src/native/unix/native/java.c?rev=1130635&r1=1130634&r2=1130635&view=diff
==============================================================================
--- commons/proper/daemon/trunk/src/native/unix/native/java.c (original)
+++ commons/proper/daemon/trunk/src/native/unix/native/java.c Thu Jun  2 16:29:44 2011
@@ -105,6 +105,31 @@ char *java_library(arg_data *args, home_
 
 typedef jint (*jvm_create_t)(JavaVM **, JNIEnv **, JavaVMInitArgs *);
 
+bool java_signal(void)
+{
+    jmethodID method;
+    jboolean ret;
+    char start[] = "signal";
+    char startparams[] = "()Z";
+
+    jsvc_xlate_to_ascii(start);
+    jsvc_xlate_to_ascii(startparams);
+    method = (*env)->GetStaticMethodID(env, cls, start, startparams);
+    if (method == NULL) {
+        (*env)->ExceptionClear(env);
+        log_error("Cannot find DaemonLoader \"signal\" method");
+        return false;
+    }
+
+    ret = (*env)->CallStaticBooleanMethod(env, cls, method);
+    /* Clear any pending exception
+     * so we can continue calling native methods
+     */
+    (*env)->ExceptionClear(env);
+    log_debug("Daemon signal method returned %s", ret ? "true" : "false");
+    return ret;
+}
+
 /* Initialize the JVM and its environment, loading libraries and all */
 bool java_init(arg_data *args, home_data *data)
 {

Modified: commons/proper/daemon/trunk/src/native/unix/native/java.h
URL: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/src/native/unix/native/java.h?rev=1130635&r1=1130634&r2=1130635&view=diff
==============================================================================
--- commons/proper/daemon/trunk/src/native/unix/native/java.h (original)
+++ commons/proper/daemon/trunk/src/native/unix/native/java.h Thu Jun  2 16:29:44 2011
@@ -24,6 +24,7 @@ char *java_library(arg_data *args, home_
 bool java_init(arg_data *args, home_data *data);
 bool java_destroy(void);
 bool java_load(arg_data *args);
+bool java_signal(void);
 bool java_start(void);
 bool java_stop(void);
 bool java_version(void);

Modified: commons/proper/daemon/trunk/src/native/unix/native/jsvc-unix.c
URL: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/src/native/unix/native/jsvc-unix.c?rev=1130635&r1=1130634&r2=1130635&view=diff
==============================================================================
--- commons/proper/daemon/trunk/src/native/unix/native/jsvc-unix.c (original)
+++ commons/proper/daemon/trunk/src/native/unix/native/jsvc-unix.c Thu Jun  2 16:29:44 2011
@@ -57,9 +57,11 @@ pid_t logger_pid = 0;           /* the l
 static bool stopping = false;
 static bool doreload = false;
 static bool doreopen = false;
+static bool dosignal = false;
 typedef void (*sighandler_t)(int);
 static sighandler_t handler_int  = NULL;
 static sighandler_t handler_usr1 = NULL;
+static sighandler_t handler_usr2 = NULL;
 static sighandler_t handler_hup  = NULL;
 static sighandler_t handler_trm  = NULL;
 
@@ -129,6 +131,10 @@ static void handler(int sig)
         case SIGUSR1:
              log_debug("Caught SIGUSR1: Reopening logs");
              doreopen = true;
+	break;
+        case SIGUSR2:
+	     log_debug("Caught SIGUSR2: Scheduling a custom signal");
+             dosignal = true;
         break;
         default:
             log_debug("Caught unknown signal %d", sig);
@@ -374,6 +380,7 @@ static void controller(int sig)
         case SIGINT:
         case SIGHUP:
         case SIGUSR1:
+        case SIGUSR2:
             log_debug("Forwarding signal %d to process %d", sig, controlled);
             kill(controlled, sig);
             signal(sig, controller);
@@ -711,6 +718,7 @@ static int child(arg_data *args, home_da
     /* Install signal handlers */
     handler_hup = signal_set(SIGHUP, handler);
     handler_usr1 = signal_set(SIGUSR1, handler);
+    handler_usr2 = signal_set(SIGUSR2, handler);
     handler_trm = signal_set(SIGTERM, handler);
     handler_int = signal_set(SIGINT, handler);
     controlled = getpid();
@@ -729,6 +737,10 @@ static int child(arg_data *args, home_da
             doreopen = false;
             set_output(args->outfile, args->errfile, args->redirectstdin, args->procname);
         }
+        if(dosignal) {
+            dosignal = false;
+            java_signal();
+        }
     }
     remove_tmp_file(args);
     log_debug("Shutdown or reload requested: exiting");
@@ -1110,6 +1122,7 @@ static int run_controller(arg_data *args
 #endif
         signal(SIGHUP, controller);
         signal(SIGUSR1, controller);
+        signal(SIGUSR2, controller);
         signal(SIGTERM, controller);
         signal(SIGINT, controller);
 

Modified: commons/proper/daemon/trunk/src/test/org/apache/commons/daemon/SimpleDaemon.java
URL: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/src/test/org/apache/commons/daemon/SimpleDaemon.java?rev=1130635&r1=1130634&r2=1130635&view=diff
==============================================================================
--- commons/proper/daemon/trunk/src/test/org/apache/commons/daemon/SimpleDaemon.java (original)
+++ commons/proper/daemon/trunk/src/test/org/apache/commons/daemon/SimpleDaemon.java Thu Jun  2 16:29:44 2011
@@ -29,7 +29,7 @@ import org.apache.commons.daemon.Daemon;
 import org.apache.commons.daemon.DaemonController;
 import org.apache.commons.daemon.DaemonContext;
 
-public class SimpleDaemon implements Daemon, Runnable {
+public class SimpleDaemon implements Daemon, Runnable, DaemonUserSignal {
 
     private ServerSocket server=null;
     private Thread thread=null;
@@ -37,6 +37,7 @@ public class SimpleDaemon implements Dae
     private volatile boolean stopping=false;
     private String directory=null;
     private Vector handlers=null;
+    private boolean softReloadSignalled;
 
     public SimpleDaemon() {
         super();
@@ -108,7 +109,10 @@ public class SimpleDaemon implements Dae
         System.err.println("SimpleDaemon: started acceptor loop");
         try {
             while(!this.stopping) {
+                checkForReload();
                 Socket socket=this.server.accept();
+                checkForReload();
+
                 Handler handler=new Handler(socket,this,this.controller);
                 handler.setConnectionNumber(number++);
                 handler.setDirectoryName(this.directory);
@@ -132,6 +136,22 @@ public class SimpleDaemon implements Dae
         System.err.println("SimpleDaemon: exiting acceptor loop");
     }
 
+    public void signal() {
+        /* In this example we are using soft reload on
+         * custom signal.
+         */
+        this.softReloadSignalled = true;
+    }
+
+    private void checkForReload() {
+      if (this.softReloadSignalled) {
+        System.err.println("SimpleDaemon: picked up reload, waiting for connections to finish...");
+        while (! this.handlers.isEmpty()) {}
+        System.err.println("SimpleDaemon: all connections have finished, pretending to reload");
+        this.softReloadSignalled = false;
+      }
+    }
+
     protected void addHandler(Handler handler) {
         synchronized (handler) {
             this.handlers.add(handler);
@@ -225,7 +245,8 @@ public class SimpleDaemon implements Dae
                         out.println("    2) Reload");
                         out.println("    3) Create a file");
                         out.println("    4) Disconnect");
-                        out.print("Your choiche: ");
+                        out.println("    5) Soft reload");
+                        out.print("Your choice: ");
                     }
 
                     /* Read an option from the client */
@@ -278,6 +299,10 @@ public class SimpleDaemon implements Dae
                         case '4':
                             out.println("Disconnecting...");
                             return;
+                        case '5':
+                            out.println("Reloading configuration...");
+                            this.parent.signal();
+                            return;
 
                         /* Discard any carriage return / newline characters */
                         case '\r':