commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r1148760 - in /commons/sandbox/runtime/trunk/src/main: java/org/apache/commons/runtime/platform/windows/ native/ native/os/win32/ test/org/apache/commons/runtime/
Date Wed, 20 Jul 2011 13:30:05 GMT
Author: mturk
Date: Wed Jul 20 13:30:04 2011
New Revision: 1148760

URL: http://svn.apache.org/viewvc?rev=1148760&view=rev
Log:
Add win32 console handler for catching console events. Sadly we cant do signals on posix cause
JVM messes that up

Added:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlEvent.java
  (with props)
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlHandler.java
  (with props)
    commons/sandbox/runtime/trunk/src/main/native/os/win32/console.c   (with props)
    commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestConsole.java
  (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java
    commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in

Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlEvent.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlEvent.java?rev=1148760&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlEvent.java
(added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlEvent.java
Wed Jul 20 13:30:04 2011
@@ -0,0 +1,74 @@
+/* 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.runtime.platform.windows;
+
+/**
+ * The type of control signal received by the ConsoleHandler.
+ */
+public enum ConsoleControlEvent
+{
+
+    /**
+     * Unknown event.
+     */
+    UNKNOWN(              -1),
+    /**
+     * A CTRL+C signal was received, either from keyboard input
+     * or from a signal generated by the {@code Console.generateEvent}
+     * method.
+     */
+    CTRL_C_EVENT(           0),
+    /**
+     * Notifies a service that it should stop.<BR/>
+     * After sending the stop request to a service, you should not send
+     * other controls to the service.
+     */
+    CTRL_BREAK_EVENT(       1),
+    /**
+     * Notifies a service that it should pause.
+     */
+    CTRL_CLOSE_EVENT(       2),
+    /**
+     * Notifies a paused service that it should resume.
+     */
+    CTRL_LOGOFF_EVENT(      5),
+    /**
+     * Notifies a service that it should report its current status
+     * information to the service control manager.
+     */
+    CTRL_SHUTDOWN_EVENT(    4);
+
+    private int value;
+    private ConsoleControlEvent(int v)
+    {
+        value = v;
+    }
+
+    public int valueOf()
+    {
+        return value;
+    }
+
+    public static ConsoleControlEvent valueOf(int value)
+    {
+        for (ConsoleControlEvent e : values()) {
+            if (e.value == value)
+                return e;
+        }
+        return UNKNOWN;
+    }
+}

Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlEvent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlHandler.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlHandler.java?rev=1148760&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlHandler.java
(added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlHandler.java
Wed Jul 20 13:30:04 2011
@@ -0,0 +1,111 @@
+/* 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.runtime.platform.windows;
+
+import org.apache.commons.runtime.Callback;
+/**
+ * The type of control signal received by the ConsoleHandler.
+ */
+public abstract class ConsoleControlHandler implements Callback
+{
+    private long        handler;
+    private native long add0();
+    private native void del0(long handler);
+
+    private boolean     registered = false;
+
+    private static native void init0();
+
+    static {
+        init0();
+    }
+
+    /**
+     * Creates a new object instance
+     */
+    protected ConsoleControlHandler()
+    {
+        handler = 0L;
+    }
+
+    @Override
+    public int handler(Object thiz, int code)
+    {
+        try {
+            return onEvent(ConsoleControlEvent.valueOf(code)) ? 1 : 0;
+        } catch (Exception x) {
+            return 0;
+        }
+    }
+
+    /**
+     * Application provided handler method.
+     */
+    protected abstract boolean onEvent(ConsoleControlEvent ctrl)
+        throws Exception;
+
+
+    /**
+     * Registers this handler to the list of handler
+     * functions for the calling process.
+     * <p>
+     * <b>Warning:</b>The standard Java mechanism for handling
+     * console events will be bypassed if {@code handler} method
+     * return true.
+     * </b>
+     *
+     * @return true if this handler was successfully added.
+     */
+    public synchronized final boolean register()
+    {
+        if (registered)
+            return true;
+        if ((handler = add0()) != 0L)
+            registered = true;
+        return registered;
+    }
+
+    /**
+     * Unregisters this handler to the list of handler
+     * functions for the calling process.
+     */
+    public synchronized final void unregister()
+    {
+        if (registered) {
+            del0(handler);
+            handler    = 0L;
+            registered = false;
+        }
+    }
+
+    /**
+     * Called by the garbage collector when the object is destroyed.
+     * The class will free internal resources allocated by the
+     * Operating system only if there are no additional references
+     * to this object.
+     *
+     * @see Object#finalize()
+     * @throws Throwable the {@code Exception} raised by this method.
+     */
+    @Override
+    protected final void finalize()
+        throws Throwable
+    {
+        unregister();
+    }
+
+}

Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ConsoleControlHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java?rev=1148760&r1=1148759&r2=1148760&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java
(original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java
Wed Jul 20 13:30:04 2011
@@ -361,7 +361,7 @@ public final class Service implements Cl
     {
         if (handle == 0L)
             throw new InvalidHandleException();
-        int nargs = args == null ? 0 : args.length;
+        int nargs = args.length;
         int rc = Win32.StartService(handle, nargs, args);
         if (rc != 0) {
             if (Status.IS_EACCES(rc))
@@ -374,6 +374,26 @@ public final class Service implements Cl
     }
 
     /**
+     * Starts a service.
+     *
+     */
+    public void start()
+        throws InvalidHandleException, SystemException, TimeoutException
+    {
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        int rc = Win32.StartService(handle, 0, null);
+        if (rc != 0) {
+            if (Status.IS_EACCES(rc))
+                throw new SecurityException(Status.describe(rc));
+            else if (rc == ERROR_SERVICE_REQUEST_TIMEOUT)
+                throw new TimeoutException();
+            else
+                throw new SystemException(Status.describe(rc));
+        }
+    }
+
+    /**
      * Sends a control code to a service.
      *
      * @param c the control code to send.
@@ -395,6 +415,26 @@ public final class Service implements Cl
     }
 
     /**
+     * Stop the service.
+     * This is the same as calling {@code control(ServiceControl.STOP)}.
+     */
+    public void stop()
+        throws InvalidHandleException, SystemException, TimeoutException
+    {
+        control(ServiceControl.STOP);
+    }
+
+    /**
+     * Pause the service.
+     * This is the same as calling {@code control(ServiceControl.PAUSE)}.
+     */
+    public void pause()
+        throws InvalidHandleException, SystemException, TimeoutException
+    {
+        control(ServiceControl.PAUSE);
+    }
+
+    /**
      * Sends a user-defined control code to a service.
      * <p>
      * The service defines the action associated with the control code.

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=1148760&r1=1148759&r2=1148760&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Wed Jul 20 13:30:04 2011
@@ -75,6 +75,7 @@ ZLIB_SOURCES=\
 ASMSOURCES=
 
 WIN32_SOURCES=\
+	$(TOPDIR)\os\win32\console.c \
 	$(TOPDIR)\os\win32\dirent.c \
 	$(TOPDIR)\os\win32\dso.c \
 	$(TOPDIR)\os\win32\exec.c \

Added: commons/sandbox/runtime/trunk/src/main/native/os/win32/console.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/console.c?rev=1148760&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/console.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/console.c Wed Jul 20 13:30:04 2011
@@ -0,0 +1,111 @@
+/* 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.
+ */
+
+#include "acr/string.h"
+#include "acr/debug.h"
+#include "acr/memory.h"
+#include "acr/jniapi.h"
+#include "acr/port.h"
+#include "acr/ring.h"
+#include "acr/clazz.h"
+#include "acr/misc.h"
+#include "acr/callback.h"
+#include "arch_opts.h"
+
+typedef struct cc_elem_t cc_elem_t;
+struct cc_elem_t {
+    ACR_RING_ENTRY(cc_elem_t) link;
+    acr_callback_t  *cb;
+};
+
+typedef struct cc_set_t {
+    /* A ring containing all of the cc_elem_t that are active
+     */
+    ACR_RING_HEAD(cc_elem_ring_t, cc_elem_t) cc_ring;
+
+} cc_set_t;
+
+static cc_set_t         ccset;
+static CRITICAL_SECTION ccmutex;
+static int              ccinit = 0;
+
+static BOOL WINAPI chandler(DWORD cc)
+{
+    cc_elem_t *e;
+    BOOL handled   = FALSE;
+    JNIEnv    *env = AcrGetJNIEnv();
+
+    EnterCriticalSection(&ccmutex);
+    ACR_RING_FOREACH(e, &ccset.cc_ring, cc_elem_t, link) {
+        if (e->cb != 0) {
+            int rc;
+            if (AcrCallbackRun(env, e->cb, 0, cc, &rc) == 0) {
+                if (handled == FALSE)
+                    handled = rc;
+            }
+        }
+    }
+    LeaveCriticalSection(&ccmutex);
+    return handled;
+}
+
+
+ACR_WIN_EXPORT(void, ConsoleControlHandler, init0)(JNI_STDARGS)
+{
+    ACR_RING_INIT(&ccset.cc_ring, cc_elem_t, link);
+    InitializeCriticalSection(&ccmutex);
+}
+
+ACR_WIN_EXPORT(jlong, ConsoleControlHandler, add0)(JNI_STDARGS)
+{
+    cc_elem_t *e;
+
+    e = ACR_TALLOC(cc_elem_t);
+    if (e == 0)
+        return 0;
+    e->cb = AcrCallbackAttach(env, obj, 0, 0, ACR_CALLBACK_NORMAL, 0);
+    if (e->cb == 0) {
+        AcrFree(e);
+        return 0;
+    }
+    EnterCriticalSection(&ccmutex);
+    if (ccinit == 0) {
+        if (SetConsoleCtrlHandler(chandler, TRUE))
+            ccinit = 1;
+    }
+    ACR_RING_ELEM_INIT(e, link);
+    ACR_RING_INSERT_HEAD(&ccset.cc_ring, e, cc_elem_t, link);
+    LeaveCriticalSection(&ccmutex);
+    return P2J(e);
+}
+
+ACR_WIN_EXPORT(void, ConsoleControlHandler, del0)(JNI_STDARGS, jlong pe)
+{
+    cc_elem_t *e = J2P(pe, cc_elem_t *);
+
+    EnterCriticalSection(&ccmutex);
+    ACR_RING_REMOVE(e, link);
+    if (ACR_RING_EMPTY(&ccset.cc_ring, cc_elem_t, link)) {
+        /* Remove the console handler.
+         * The next add will init that again.
+         */
+        SetConsoleCtrlHandler(chandler, FALSE);
+        ccinit = 0;
+    }
+    LeaveCriticalSection(&ccmutex);
+    AcrCallbackFree(env, e->cb);
+    AcrFree(e);
+}

Propchange: commons/sandbox/runtime/trunk/src/main/native/os/win32/console.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestConsole.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestConsole.java?rev=1148760&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestConsole.java
(added)
+++ commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestConsole.java
Wed Jul 20 13:30:04 2011
@@ -0,0 +1,68 @@
+/* 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.runtime.platform.windows;
+
+import java.io.IOException;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import org.testng.annotations.*;
+import org.testng.Assert;
+
+public class TestConsole extends Assert
+{
+    static Thread thThread;
+
+    class MyHandler extends ConsoleControlHandler
+    {
+        public MyHandler()
+        {
+        }
+
+        @Override
+        public boolean onEvent(ConsoleControlEvent ev)
+        {
+            System.out.println("Received " + ev);
+            thThread.interrupt();
+            return true;
+        }
+    }
+
+    @Test(groups = { "windows" })
+    public void testHandler()
+        throws Exception
+    {
+        thThread = Thread.currentThread();
+        MyHandler h = new MyHandler();
+        assertTrue(h.register());
+        /* XXX: The following code doesn't work
+         *      because ant redirects the console
+         *      and there is no stdin.
+         *
+        System.out.println("You can now enter any console event");
+        System.out.println("Sleeping for 60 seconds ...");
+        try {
+            Thread.sleep(60000);
+        } catch (Exception x) {
+            System.out.println("Interrupted.");
+        }
+        */
+        h.unregister();
+    }
+
+
+}

Propchange: commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestConsole.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message