Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9FB187C69 for ; Wed, 20 Jul 2011 13:30:32 +0000 (UTC) Received: (qmail 42484 invoked by uid 500); 20 Jul 2011 13:30:32 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 42403 invoked by uid 500); 20 Jul 2011 13:30:31 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 42396 invoked by uid 99); 20 Jul 2011 13:30:31 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 20 Jul 2011 13:30:31 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 20 Jul 2011 13:30:26 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DF27123888CE for ; Wed, 20 Jul 2011 13:30:05 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@commons.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110720133005.DF27123888CE@eris.apache.org> 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.
+ * 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. + *

+ * Warning:The standard Java mechanism for handling + * console events will be bypassed if {@code handler} method + * return true. + * + * + * @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. *

* 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