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/09 18:22:56 UTC

svn commit: r813035 - in /commons/sandbox/runtime/trunk/src/main/native: include/acr_signals.h include/arch/windows/acr_arch_private.h os/unix/signals.c os/win32/main.c os/win32/mutex.c os/win32/sema.c os/win32/signals.c

Author: mturk
Date: Wed Sep  9 16:22:56 2009
New Revision: 813035

URL: http://svn.apache.org/viewvc?rev=813035&view=rev
Log:
First part of Win32 signal processing

Modified:
    commons/sandbox/runtime/trunk/src/main/native/include/acr_signals.h
    commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h
    commons/sandbox/runtime/trunk/src/main/native/os/unix/signals.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/mutex.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/sema.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_signals.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_signals.h?rev=813035&r1=813034&r2=813035&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_signals.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_signals.h Wed Sep  9 16:22:56 2009
@@ -35,7 +35,7 @@
  * ACR-private function for initializing the signal package
  * @internal
  */
-void acr_SignalsInit(void);
+int acr_SignalsInit(void);
 
 /**
  * Get the description for a specific signal number

Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h?rev=813035&r1=813034&r2=813035&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch_private.h Wed Sep  9 16:22:56 2009
@@ -131,9 +131,38 @@
 DWORD        ACR_SetSecurityInfo(HANDLE, int, PSID, PSID, int);
 
 /**
- * Heap allocation from main.c
+ * Events from main.c
  */
 extern HANDLE dll_psig_handle;
+extern HANDLE dll_auto_hevent;
+
+/**
+ * Local functions from signal.c
+ */
+DWORD        ACR_DeliverSignals(void);
+extern volatile LONG current_signal_listeners;
+#define ACR_SIGNAL_REGISTER() InterlockedIncrement(&current_signal_listeners)
+#define ACR_SIGNAL_RECEIVED() InterlockedDecrement(&current_signal_listeners)
+#define ACR_SIGNAL_NWAITERS() InterlockedCompareExchange(&current_signal_listeners, 0, 0)
+
+static ACR_INLINE DWORD ACR_WaitForObjectAndSignal(HANDLE handle, DWORD dwTimeout)
+{
+    DWORD  rc;
+    HANDLE wh[2];
+
+    wh[0] = dll_psig_handle;
+    wh[1] = handle;
+    ACR_SIGNAL_REGISTER();
+    rc =  WaitForMultipleObjectsEx(2, wh, FALSE, dwTimeout, TRUE);
+    ACR_SIGNAL_RECEIVED();
+
+    return rc;
+}
+
+
+/**
+ * Heap allocation from main.c
+ */
 extern HANDLE dll_heap_handle;
 
 #define ACR_HeapMalloc(S)   HeapAlloc(dll_heap_handle, 0, (S))

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=813035&r1=813034&r2=813035&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 Wed Sep  9 16:22:56 2009
@@ -36,7 +36,7 @@
 #define ACR_NUMSIG  33
 #endif
 
-void acr_SignalsInit()
+int acr_SignalsInit()
 {
 
 }

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c?rev=813035&r1=813034&r2=813035&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c Wed Sep  9 16:22:56 2009
@@ -35,6 +35,7 @@
 static DWORD            dll_tls_index = TLS_OUT_OF_INDEXES;
 HANDLE                  dll_heap_handle = NULL;
 HANDLE                  dll_psig_handle = NULL;
+HANDLE                  dll_auto_hevent = NULL;
 
 static SYSTEM_INFO      osinf;
 static OSVERSIONINFOEXA osver;
@@ -323,7 +324,20 @@
      * first wait handle instead WaitForSingleObjects and
      * call signal dispatching function when such event occurs.
      */
-    dll_psig_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
+    dll_auto_hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (IS_INVALID_HANDLE(dll_auto_hevent))
+        return ACR_GET_OS_ERROR();
+
+    /*
+     * Create a simple unnamed signaling event.
+     * We use mnual reset event meaning that if multiple
+     * objects are waiting on that even all of them
+     * will receive the signal.
+     * Always use WaitForMultipleObjects with this handle as
+     * first wait handle instead WaitForSingleObjects and
+     * call signal dispatching function when such event occurs.
+     */
+    dll_psig_handle = CreateEvent(NULL, TRUE, FALSE, NULL);
     if (IS_INVALID_HANDLE(dll_psig_handle))
         return ACR_GET_OS_ERROR();
 

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/mutex.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/mutex.c?rev=813035&r1=813034&r2=813035&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/mutex.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/mutex.c Wed Sep  9 16:22:56 2009
@@ -120,25 +120,22 @@
 {
     int rc;
     DWORD  ws;
-    HANDLE wh[2];
+    HANDLE m = (HANDLE)ACR_IOH_FDATA(mutex);
 
-    wh[0] = dll_psig_handle;
-    wh[1] = (HANDLE)ACR_IOH_FDATA(mutex);
     if (ACR_IOH_FTYPE(mutex) != ACR_DT_MUTEX) {
         return ACR_EFTYPE;
     }
-    if (IS_INVALID_HANDLE(wh[0])) {
+    if (IS_INVALID_HANDLE(m)) {
         return ACR_EBADF;
     }
     do {
         rc = 0;
-        ws = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);
-
+        ws = ACR_WaitForObjectAndSignal(m, INFINITE);
         if (ws == WAIT_OBJECT_0) {
             /* Signal event is set
-             * TODO: Deliver a signal
+             * Get it's satus.
              */
-            rc = ACR_EINTR;
+            rc = ACR_DeliverSignals();
         }
         else if (ws == WAIT_OBJECT_0 + 1 || ws == WAIT_ABANDONED_0 + 1) {
             /* We got the lock */

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/sema.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/sema.c?rev=813035&r1=813034&r2=813035&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/sema.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/sema.c Wed Sep  9 16:22:56 2009
@@ -156,7 +156,6 @@
 {
     int rc;
     DWORD  ws;
-    HANDLE wh[2];
     HANDLE s = (HANDLE)ACR_IOH_FDATA(sema);
 
     if (ACR_IOH_FTYPE(sema) != ACR_DT_SEMAPHORE) {
@@ -166,17 +165,15 @@
         return ACR_EBADF;
     }
 
-    wh[0] = dll_psig_handle;
-    wh[1] = s;
     do {
         rc = 0;
-        ws = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);
+        ws = ACR_WaitForObjectAndSignal(s, INFINITE);
 
         if (ws == WAIT_OBJECT_0) {
-            /* Signal event is set
-             * TODO: Deliver a signal
+            /* Signal event is set.
+             * Get it's satus.
              */
-            rc = ACR_EINTR;
+            rc = ACR_DeliverSignals();
         }
         else if (ws == WAIT_OBJECT_0 + 1) {
             /* We got the lock */

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c?rev=813035&r1=813034&r2=813035&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/signals.c Wed Sep  9 16:22:56 2009
@@ -45,9 +45,112 @@
 #define ACR_NUMSIG  33
 #endif
 
-void acr_SignalsInit()
+static CRITICAL_SECTION signal_lock;
+int           dll_daemon_mode = 0;
+volatile LONG current_signal_value;
+volatile LONG current_signal_listeners;
+
+/*
+ * Make sure this handler is initialized again
+ * after JVM is loaded. JVM installs it's own ConsoleHandler
+ * that is of no use to us.
+ * We handle all signals so the returned value from this callback is
+ * allways TRUE (handled).
+ */
+static BOOL WINAPI console_event_handler(DWORD sig)
+{
+    LONG posix_signal = 0;
+    switch (sig) {
+        case CTRL_C_EVENT:
+            posix_signal = SIGHUP;
+        break;
+        case CTRL_BREAK_EVENT:
+            posix_signal = SIGINT;
+        break;
+        case CTRL_CLOSE_EVENT:
+            posix_signal = SIGQUIT;
+        break;
+        case CTRL_LOGOFF_EVENT:
+            /* Something not defined in POSIX land
+             * This might be our user logging off or
+             * if we are running as a service we just got an
+             * info that someone logged off.
+             */
+            if (dll_daemon_mode == 0)
+                posix_signal = SIGTSTP;
+            else
+                posix_signal = SIGQUIT;
+        break;
+        case CTRL_SHUTDOWN_EVENT:
+            posix_signal = SIGKILL;
+        break;
+    }
+    if (posix_signal) {
+        /* Sync with callback handler */
+        EnterCriticalSection(&signal_lock);
+        InterlockedExchange(&current_signal_value, posix_signal);
+        /* Fire the signal events.
+         * The first locked listener will handle
+         * the signal.
+         */
+        SetEvent(dll_auto_hevent);
+        SetEvent(dll_psig_handle);
+        LeaveCriticalSection(&signal_lock);
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
+
+int acr_SignalsInit()
 {
+    if (!InitializeCriticalSectionAndSpinCount(&signal_lock, ACR_SPINCOUNT)) {
+        return ACR_GET_OS_ERROR();
+    }
 
+    return 0;
+}
+
+/*
+ * Called when WaitForMultipleObjects gets signal.
+ * Return value ACR_EINTR means that is safe for waiter
+ * to restart the Wait operation.
+ * Any other value (ACR_INCOMPLETE) must break the current
+ * blocking operation.
+ */
+DWORD ACR_DeliverSignals()
+{
+    DWORD rc = ACR_EINTR;
+    /* We are invoked from one of the waiters.
+     *
+     */
+    EnterCriticalSection(&signal_lock);
+    if (ACR_SIGNAL_NWAITERS() == 0) {
+        /* Main signal dispatching.
+         *
+         */
+
+        /* Getting here means we are the last thread that left
+         * wait function for signal event.
+         * Make the signal event is back to non signaled state.
+         */
+        ResetEvent(dll_psig_handle);
+    }
+    else {
+        /* Someone just entered while we obtained the lock
+         */
+    }
+    switch (current_signal_value) {
+        case SIGKILL:
+        case SIGQUIT:
+            rc = ACR_INCOMPLETE;
+        default:
+            rc = ACR_EINTR;
+        break;
+    }
+    LeaveCriticalSection(&signal_lock);
+    return rc;
 }
 
 ACR_DECLARE(const char *) ACR_SignalDescription(int signum)
@@ -59,4 +162,3 @@
     else
         return "Unknown signal (number)";
 }
-