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/14 15:18:30 UTC

svn commit: r814630 - in /commons/sandbox/runtime/trunk/src: main/native/include/ main/native/include/arch/windows/ main/native/os/unix/ main/native/os/win32/ main/native/test/ test/org/apache/commons/runtime/

Author: mturk
Date: Mon Sep 14 13:18:30 2009
New Revision: 814630

URL: http://svn.apache.org/viewvc?rev=814630&view=rev
Log:
More on win32 signals. Lot's of debugging in there that will go away

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/signals.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/wusec.c
    commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c
    commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSemaphore.java

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=814630&r1=814629&r2=814630&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 Mon Sep 14 13:18:30 2009
@@ -44,9 +44,16 @@
  */
 ACR_DECLARE(const char *) ACR_SignalDescription(int signum);
 
+/**
+ * Send a signal to the process.
+ * @param sal Signal security key.
+ * @param sig signal to send.
+ * @param to pid of the process
+ */
+ACR_DECLARE(int) ACR_SendSignal(const acr_pchar_t *salt, int signum, int to);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* _ACR_SIGNALS_H */
-

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=814630&r1=814629&r2=814630&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 Mon Sep 14 13:18:30 2009
@@ -134,6 +134,8 @@
 LPVOID       ACR_StdSecurityDescriptor(JNIEnv *, int, int);
 DWORD        ACR_SetSecurityInfo(HANDLE, int, PSID, PSID, int);
 
+PSECURITY_ATTRIBUTES ACR_GetSaWithNullDacl(void);
+
 /**
  * Events from main.c
  */

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=814630&r1=814629&r2=814630&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 Mon Sep 14 13:18:30 2009
@@ -53,3 +53,7 @@
         return "Unknown signal (number)";
 }
 
+ACR_DECLARE(int) ACR_SendSignal(const char *salt, int signum, int to)
+{
+    return ACR_ENOTIMPL;
+}

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=814630&r1=814629&r2=814630&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 Mon Sep 14 13:18:30 2009
@@ -306,17 +306,13 @@
                   L"Failed loading system libraries", rc);
         return (int)rc;
     }
-
-    if ((rc = acr_SignalsInit())) {
-        /* Failed initializing signaling sub system
-         */        
-        return (int)rc;        
-    }
     /* Up to here we can be called multiple times.
      */
-    if (initialized++)
-        return 0;
-
+    if (initialized++) {
+        /* Second invocation for signal init
+         */
+        return acr_SignalsInit();
+    }
     while (sePrivileges[i]) {
         if ((rc = ACR_EnablePrivilege(sePrivileges[i])) != ERROR_SUCCESS) {
             wchar_t buf[128];
@@ -363,11 +359,17 @@
      */
     em = SetErrorMode(0);
     SetErrorMode(em | SEM_NOOPENFILEERRORBOX);
+    if ((rc = acr_SignalsInit())) {
+        /* Failed initializing signaling sub system
+         */
+        return (int)rc;
+    }
 #if defined(DEBUG)
     fprintf(stdout, "\nInitialized ACR : %S\n", dll_file_name);
     fprintf(stdout, "                : %S\n", dos_file_name);
     fflush(stdout);
 #endif
+
     return 0;
 }
 

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=814630&r1=814629&r2=814630&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 Mon Sep 14 13:18:30 2009
@@ -55,6 +55,16 @@
 volatile LONG current_signal_listeners;
 
 static SIG_PF signal_handlers[ACR_NUMSIG];
+static volatile int signal_handlers_running;
+
+
+/* We use 4 instances as default
+ * The real number should be numCPU * 2
+ */
+static int      sig_pipe_instances = 4;
+static HANDLE   sig_pipe_handle    = INVALID_HANDLE_VALUE;
+static wchar_t  sig_pipe_name[64];
+static wchar_t  sig_pipe_salt[64];
 
 static void make_security_cookie(acr_sig_msg_t *msg, const wchar_t *salt,
                                  DWORD sn, DWORD to)
@@ -64,7 +74,7 @@
     acr_uint32_t tc = GetTickCount();
 
     ACR_SHA1Init(&sha);
-    if (salt)
+    if (salt && *salt)
         ACR_SHA1UpdateW(&sha, salt, wcslen(salt));
     ACR_SHA1Update(&sha, (unsigned char *)&sn, sizeof(acr_uint32_t));
     ACR_SHA1Update(&sha, (unsigned char *)&me, sizeof(acr_uint32_t));
@@ -84,7 +94,7 @@
     acr_uint32_t me = GetCurrentProcessId();
 
     ACR_SHA1Init(&sha);
-    if (salt)
+    if (salt && *salt)
         ACR_SHA1UpdateW(&sha, salt, wcslen(salt));
 
     ACR_SHA1Update(&sha, (unsigned char *)&(msg->signal), sizeof(acr_uint32_t));
@@ -97,6 +107,27 @@
     return memcmp(digest, msg->cookie, 20);
 }
 
+/* Write an empty message to the pipe.
+ * So we can bail out from the ConnectNamedPipe call
+ */
+static void ping_sig_pipe(int state)
+{
+    DWORD  read = 0;
+    acr_sig_msg_t msg;
+
+    signal_handlers_running = state;
+    if (IS_INVALID_HANDLE(sig_pipe_handle))
+        return;
+    memset(&msg, 0, sizeof(acr_sig_msg_t));
+    CallNamedPipeW(sig_pipe_name,
+                   &msg,
+                   (DWORD)sizeof(acr_sig_msg_t),
+                   &msg,
+                   (DWORD)sizeof(acr_sig_msg_t),
+                   &read,
+                   NMPWAIT_NOWAIT);
+}
+
 /* Default signal handler.
  */
 static void default_signal_handler(int sig)
@@ -104,6 +135,7 @@
     JNIEnv *_E;
     switch (sig) {
         case SIGKILL:
+            ping_sig_pipe(0);
             /* Call the System.exit(9)
              */
             if (ACR_SystemExit(NULL, sig)) {
@@ -117,6 +149,7 @@
         break;
         case SIGBUS:
         case SIGSEGV:
+            ping_sig_pipe(0);
             _E = ACR_GetJNIEnv();
             if (IS_VALID_HANDLE(_E)) {
                 (*_E)->FatalError(_E, strsignal(sig));
@@ -132,6 +165,7 @@
             /* Do nothing */
 #if defined(DEBUG)
             fprintf(stderr, "[native] Unhandled - %s\n", strsignal(sig));
+            fflush(stderr);
 #endif
         break;
     }
@@ -197,15 +231,127 @@
          * the signal.
          */
         SetEvent(dll_auto_hevent);
-        SetEvent(dll_psig_handle);
         LeaveCriticalSection(&signal_lock);
-        handled = TRUE;
+        if (signal_handlers[posix_signal] == SIG_DFL) {
+#if defined(DEBUG)
+            fprintf(stdout, "[native] Default console handler for - %s\n",
+                            strsignal(posix_signal));
+            fflush(stdout);
+#endif
+            /* Execute default signal hadler
+             */
+        }
+        else
+            handled = TRUE;
     }
     return handled;
 }
 
-static volatile int signal_handlers_running;
+static DWORD WINAPI read_signal_thread(LPVOID param)
+{
+    DWORD  read = 0;
+    HANDLE pipe = (HANDLE)param;
+    acr_sig_msg_t msg;
 
+#if defined(DEBUG)
+    fprintf(stdout, "Started read thread\n");
+    fflush(stdout);
+#endif
+    for (;;) {
+        memset(&msg, 0, sizeof(acr_sig_msg_t));
+        if (!ReadFile(pipe,
+                      &msg,
+                      (DWORD)sizeof(acr_sig_msg_t),
+                      &read,
+                      NULL)) {
+            /* Read failed. */
+            break;
+        }
+        if (read != sizeof(acr_sig_msg_t)) {
+            /* Invalid message size.
+             */
+#if defined(DEBUG)
+            fprintf(stderr, "Received invalid message size %d\n", read);
+            fflush(stderr);
+#endif
+            break;
+        }
+        if (verify_security_cookie(&msg, sig_pipe_salt)) {
+            /* Invalid message signature.
+             */
+#if defined(DEBUG)
+            fprintf(stderr, "Received invalid message signature\n");
+            fflush(stderr);
+#endif
+            break;
+        }
+#if defined(DEBUG)
+        fprintf(stdout, "Received valid signal %d from %d\n",
+                         msg.signal, msg.sender);
+        fflush(stdout);
+#endif
+        msg.sender = GetCurrentProcessId();
+        /* Write the message back with our pid as sender.
+         * We don't care about the result of the write operation.
+         */
+        WriteFile(pipe, &msg, (DWORD)sizeof(acr_sig_msg_t), &read, NULL);
+        FlushFileBuffers(pipe);
+        DisconnectNamedPipe(pipe);
+        CloseHandle(pipe);
+
+        /* Deliver a signal */
+        /* Sync with callback handler */
+        EnterCriticalSection(&signal_lock);
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+        /* XXX: Do we really need an atomic op here?
+         */
+        _InterlockedOr(&current_signal_queue, sigmask(msg.signal));
+#else
+        /* We don't have compiler intrinsic.
+         * CriticalSection should guard the value for the majority
+         * of cases.
+         */
+        current_signal_queue |= sigmask(msg.signal);
+#endif
+        /* Fire the signal events.
+         * The first locked listener will handle
+         * the signal.
+         */
+        SetEvent(dll_auto_hevent);
+        LeaveCriticalSection(&signal_lock);
+    }
+    CloseHandle(pipe);
+    return 0;
+}
+
+static DWORD WINAPI main_signal_monitor(LPVOID unused)
+{
+    DWORD rc;
+    while (signal_handlers_running) {
+        rc = WaitForSingleObject(dll_auto_hevent, INFINITE);
+        if (rc == WAIT_OBJECT_0) {
+            /* Dispatch the event to object waiters
+             */
+            EnterCriticalSection(&signal_lock);
+            if (ACR_SIGNAL_NWAITERS() == 0) {
+                LeaveCriticalSection(&signal_lock);
+                rc = ACR_DeliverSignals();
+            }
+            else {
+                LeaveCriticalSection(&signal_lock);
+                SetEvent(dll_psig_handle);
+            }
+        }
+        else {
+            /* Anything else is a fault.
+             * Terminate the monitor thread
+             */
+             signal_handlers_running = 0;
+             break;
+        }
+    }
+    return 0;
+}
 /* Main signal thread is responsible for handling the signal
  * events.
  * Once created it will remain running until application exit,
@@ -220,13 +366,71 @@
     fflush(stdout);
 #endif
     while (signal_handlers_running) {
+        BOOL connected;
+        if (IS_INVALID_HANDLE(sig_pipe_handle)) {
+            sig_pipe_handle = CreateNamedPipeW(sig_pipe_name,
+                                               PIPE_ACCESS_DUPLEX,  /* ###: We only read */
+                                               PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
+                                               sig_pipe_instances,
+                                               (DWORD)sizeof(acr_sig_msg_t),
+                                               (DWORD)sizeof(acr_sig_msg_t),
+                                               2000,
+                                               ACR_GetSaWithNullDacl());
+            if (IS_INVALID_HANDLE(sig_pipe_handle)) {
+                /* Failed to create signal messaging pipe
+                 * for this process. Retry after 500ms.
+                 */
+#if defined(DEBUG)
+                fprintf(stderr, "Could not create listener pipe '%S' - %d\n",
+                                sig_pipe_name, GetLastError());
+                fflush(stderr);
+#endif
+                SleepEx(500, FALSE);
+                continue;
+            }
+        }
+#if defined(DEBUG)
+        fprintf(stdout, "Waiting for a client on '%S'\n",
+                        sig_pipe_name);
+        fflush(stdout);
+#endif
+        if (!(connected = ConnectNamedPipe(sig_pipe_handle, NULL))) {
+            if (GetLastError() == ERROR_PIPE_CONNECTED)
+                connected = TRUE;
+        }
+#if defined(DEBUG)
+        fprintf(stdout, "Client on '%S' is %s\n",
+                        sig_pipe_name, connected ? "connected" : "not connected");
+        fflush(stdout);
+#endif
+        if (connected && signal_handlers_running) {
+            /* We have connected client.
+             * Start the cleint worker thread
+             */
+            HANDLE wt;
+            DWORD  wi;
+            if (!(wt = CreateThread(NULL,
+                                    0,
+                                    read_signal_thread,
+                                    (LPVOID)sig_pipe_handle,
+                                    0,
+                                    &wi))) {
 
-        /* Until we implement the pupmp.
-         */
-        Sleep(1000);
+            }
+            else
+                CloseHandle(wt);
+
+        }
+        else {
+            /* Connect failed.
+             * Close the pipe and try again.
+             */
+            CloseHandle(sig_pipe_handle);
+        }
+        sig_pipe_handle = INVALID_HANDLE_VALUE;
     }
 #if defined(DEBUG)
-    fprintf(stdout, "\n[native] Terminated signalig subsystem for %d\n",
+    fprintf(stdout, "\n[native] Terminated signaling subsystem for %d\n",
             GetCurrentProcessId());
     fflush(stdout);
 #endif
@@ -235,7 +439,8 @@
 
 int acr_SignalsInit()
 {
-    DWORD i;
+    HANDLE h;
+    DWORD  i;
 
     /* Guard against multiple invocations.
      * We might initialize twice; in daemon and in JVM again
@@ -267,13 +472,49 @@
     signal_handlers[SIGSEGV] = default_signal_handler;
     signal_handlers[SIGKILL] = default_signal_handler;
     signal_handlers[SIGTERM] = default_signal_handler;
+    signal_handlers[SIGINT]  = SIG_DFL;
 
-    if (!CreateThread(NULL,
-                      0,
-                      main_signal_thread,
-                      NULL,
-                      0,
-                      &i)) {
+    /* Get the global signal pipe name.
+     * Combined from pid and ACR_NUMSIG.
+     */
+    pipe_name_from_pid(sig_pipe_name, GetCurrentProcessId(), ACR_NUMSIG);
+    sig_pipe_handle = CreateNamedPipeW(sig_pipe_name,
+                                       PIPE_ACCESS_DUPLEX,  /* ###: We only read */
+                                       PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
+                                       sig_pipe_instances,
+                                       (DWORD)sizeof(acr_sig_msg_t),
+                                       (DWORD)sizeof(acr_sig_msg_t),
+                                       2000,
+                                       ACR_GetSaWithNullDacl());
+    if (IS_INVALID_HANDLE(sig_pipe_handle)) {
+        /* Failed to create signal messaging pipe
+         * for this process. Bail out.
+         *
+         * ###: We could just continue from here as well.
+         *      Signal thread wold retry to create this pipe
+         *      on regular intervals.
+         */
+         return ACR_GET_OS_ERROR();
+    }
+    if (!(h = CreateThread(NULL,
+                           0,
+                           main_signal_monitor,
+                           NULL,
+                           0,
+                           &i))) {
+        /* Failed creating thread.
+         * If we ever get here the system is
+         * unstable and will probably crash
+         * in the near future. Anyhow, return the error.
+         */
+        return ACR_GET_OS_ERROR();
+    }
+    if (!(h = CreateThread(NULL,
+                           0,
+                           main_signal_thread,
+                           NULL,
+                           0,
+                           &i))) {
         /* Failed creating thread.
          * If we ever get here the system is
          * unstable and will probably crash
@@ -314,10 +555,11 @@
         /* Someone just entered while we obtained the lock
          */
     }
-    if ((mask = (current_signal_queue & ~current_signal_mask))) {
+    while ((mask = (current_signal_queue & ~current_signal_mask))) {
         int i;
-        for (i = 1; i < ACR_NUMSIG, rc == ACR_EINTR; i++) {
+        for (i = 1; i < ACR_NUMSIG; i++) {
             if (mask & sigmask(i)) {
+                SIG_PF sig = signal_handlers[i];
                 switch (i) {
                     case SIGKILL:
                     case SIGQUIT:
@@ -328,11 +570,25 @@
                         rc = ACR_EINTR;
                     break;
                 }
-                if (signal_handlers[i-1] != SIG_IGN) {
+                /* Remove the signal from the queue
+                 */
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+                /* XXX: Do we really need an atomic op here?
+                 */
+                _InterlockedAnd(&current_signal_queue, ~sigmask(msg.signal));
+#else
+                current_signal_queue &= ~sigmask(i);
+#endif
+                if (sig != SIG_IGN && sig != SIG_ERR) {
+                    LeaveCriticalSection(&signal_lock);
                     /* TODO: Handle default signals */
-                    (*signal_handlers[i-1])(i);
+                    sig(i);
+                    EnterCriticalSection(&signal_lock);
+                    break;
                 }
             }
+            if (rc != ACR_EINTR)
+                break;
         }
     }
     LeaveCriticalSection(&signal_lock);
@@ -348,3 +604,26 @@
     else
         return "Unknown signal (number)";
 }
+
+ACR_DECLARE(int) ACR_SendSignal(const wchar_t *salt, int signum, int to)
+{
+    DWORD read;
+    acr_sig_msg_t msg;
+    acr_sig_msg_t buf;
+    wchar_t name[64];
+
+    pipe_name_from_pid(name, to, ACR_NUMSIG);
+    make_security_cookie(&msg, salt, signum, to);
+    if (CallNamedPipeW(name,
+                       &msg,
+                       (DWORD)sizeof(acr_sig_msg_t),
+                       &buf,
+                       (DWORD)sizeof(acr_sig_msg_t),
+                       &read,
+                       NMPWAIT_USE_DEFAULT_WAIT)) {
+        return 0;
+    }
+    else {
+        ACR_GET_OS_ERROR();
+    }
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/wusec.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/wusec.c?rev=814630&r1=814629&r2=814630&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/wusec.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/wusec.c Mon Sep 14 13:18:30 2009
@@ -534,3 +534,57 @@
     }
     return SetSecurityInfo(handle, ko, sinf, uid, gid, dacl, NULL);
 }
+
+
+static PSECURITY_ATTRIBUTES _null_sa = NULL;
+static SECURITY_ATTRIBUTES  _empty_sa;
+/* To share the objects with other processes, we need a NULL ACL
+ * Code from MS KB Q106387
+ */
+PSECURITY_ATTRIBUTES ACR_GetSaWithNullDacl()
+{
+    DWORD rc = 0;
+    PSECURITY_DESCRIPTOR pSD;
+
+
+    if (_null_sa)
+        return _null_sa;
+
+    _null_sa  = (PSECURITY_ATTRIBUTES)LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES));
+    _null_sa->nLength = sizeof(SECURITY_ATTRIBUTES);
+
+    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
+    _null_sa->lpSecurityDescriptor = pSD;
+    if (pSD == NULL || _null_sa == NULL) {
+        rc = ACR_ENOMEM;
+        goto cleanup;
+    }
+    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
+        rc = GetLastError();
+        goto cleanup;
+    }
+    if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL)NULL, FALSE)) {
+        rc = ACR_ENOMEM;
+        goto cleanup;
+    }
+    _null_sa->lpSecurityDescriptor = pSD;
+    _null_sa->bInheritHandle       = FALSE;
+
+    SetLastError(0);
+    return _null_sa;
+
+cleanup:
+    if (pSD)
+        LocalFree(pSD);
+    if (_null_sa) {
+        LocalFree(_null_sa);
+        _null_sa = NULL;
+    }
+    _null_sa = &_empty_sa;
+    _null_sa->nLength = sizeof(SECURITY_ATTRIBUTES);
+    _null_sa->lpSecurityDescriptor = NULL;
+    _null_sa->bInheritHandle       = FALSE;
+    
+    SetLastError(rc);    
+    return _null_sa;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c?rev=814630&r1=814629&r2=814630&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/test/testsuite.c Mon Sep 14 13:18:30 2009
@@ -38,21 +38,25 @@
 #include "acr_ring.h"
 #include "acr_ini.h"
 #include "acr_port.h"
+#include "acr_signals.h"
 #include "acr_time.h"
 #include "acr_version.h"
 
 #if defined (WIN32)
 #include <io.h>
+#include <process.h>
 #include <sys/stat.h>
 #define random rand
 #define srandom srand
 #define PRINT_PSTR    "%S"
 #define STD_PREFIX    L"acr-test-"
+#define _TXT(X)       L ## X
 #else
 extern mode_t acr_default_umask;
 extern mode_t acr_default_perms;
 #define PRINT_PSTR    "%s"
 #define STD_PREFIX    "acr-test-"
+#define _TXT(X)       X
 #endif
 
 
@@ -194,7 +198,16 @@
     jvmso = argv[0];
     jvmcp = argv[1];
 
+#if defined(WIN32)
+    {
+        wchar_t pb[8192];
+        MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+                            jvmso, -1, pb, sizeof(pb));
+        dso = ACR_DsoLoad(NULL, pb);
+    }
+#else
     dso = ACR_DsoLoad(NULL, jvmso);
+#endif
     if (dso < 0) {
         fprintf(stderr, "Cannot load JVM from %s\n", jvmso);
         fflush(stderr);
@@ -429,7 +442,6 @@
 {
     int i;
     size_t mp = 0;
-    char buf[1024];
     const char *end = NULL;
 
     if (argc < 2) {
@@ -440,9 +452,13 @@
     printf("smatch returned  %d\n", i);
     printf("smatch ended on '%s'\n", argv[0] + mp);
 #if !defined(WIN32)
-    printf("original string is %s.\n", argv[0]);
-    shquote(argv[0], buf, 1024);
-    printf("quoted   string is %s.\n", buf);
+    {
+        char buf[1024];
+
+        printf("original string is %s.\n", argv[0]);
+        shquote(argv[0], buf, 1024);
+        printf("quoted   string is %s.\n", buf);
+    }
 #endif
     return 0;
 }
@@ -508,6 +524,28 @@
     return 0;
 }
 
+static int test_signal(int argc, const char *const argv[])
+{
+    int failed = 0;
+    int ppid;
+    if (argc < 1) {
+        return ACR_EINVAL;
+    }
+    if (*argv[0] == 's') {
+        printf("Server waiting %d\n", getpid());
+#if defined(WIN32)
+        Sleep(10000);
+#endif
+    }
+    else {
+        ppid = atoi(argv[0]);
+        if (ppid == 0)
+            return ACR_EINVAL;
+        ACR_SendSignal(NULL, SIGBUS, ppid);
+    }
+    return 0;
+}
+
 int main(int argc, const char *const argv[])
 {
     int rv = 0;
@@ -590,8 +628,9 @@
         else if (!strcasecmp(run_test, "pmatch")) {
             rv = test_pmatch(argc, argv);
         }
-
-        x_free(run_test);
+        else if (!strcasecmp(run_test, "signal")) {
+            rv = test_signal(argc, argv);
+        }
     }
 
 cleanup:

Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSemaphore.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSemaphore.java?rev=814630&r1=814629&r2=814630&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSemaphore.java (original)
+++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestSemaphore.java Mon Sep 14 13:18:30 2009
@@ -80,5 +80,19 @@
         }
         test003(s);
     }
+
+    public void testTestSemaphoreSleep()
+        throws Throwable
+    {
+        boolean owner = TestParams.getInstance().isChild();
+        if (owner) {
+            try {
+                System.out.println("Sleeping for 1 second");
+                Thread.sleep(1000);
+            } catch (Throwable t) {
+                // Ignore    
+            }
+        }
+    }
 }