src/jdk.jdi/windows/native/libdt_shmem/shmem_md.c
changeset 47216 71c04702a3d5
parent 25859 3317bb8137f4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jdi/windows/native/libdt_shmem/shmem_md.c	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <windows.h>
+#include <errno.h>
+
+#include "shmem_md.h"
+#include "sysShmem.h"
+#include "shmemBase.h"  /* for exitTransportWithError */
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+    #define THIS_FILE __FILE__
+#endif
+
+/*
+ * These functions are not completely universal. For now, they are used
+ * exclusively for Jbug's shared memory transport mechanism. They have
+ * been implemented on Win32 only so far, so the abstractions may not be correct
+ * yet.
+ */
+
+static HANDLE memHandle = NULL;
+
+#ifdef DEBUG
+#define sysAssert(expression) {         \
+    if (!(expression)) {                \
+            exitTransportWithError \
+            ("\"%s\", line %d: assertion failure\n", \
+             THIS_FILE, __DATE__, __LINE__); \
+    }                                   \
+}
+#else
+#define sysAssert(expression) ((void) 0)
+#endif
+
+int
+sysSharedMemCreate(const char *name, int length,
+                   sys_shmem_t *mem, void **buffer)
+{
+    void *mappedMemory;
+    HANDLE memHandle;
+
+    sysAssert(buffer);
+    sysAssert(name);
+    sysAssert(length > 0);
+
+    memHandle  =
+        CreateFileMapping(INVALID_HANDLE_VALUE, /* backed by page file */
+                          NULL,               /* no inheritance */
+                          PAGE_READWRITE,
+                          0, length,          /* hi, lo order of length */
+                          name);
+    if (memHandle == NULL) {
+        return SYS_ERR;
+    } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
+        /* If the call above didn't create it, consider it an error */
+        CloseHandle(memHandle);
+        memHandle = NULL;
+        return SYS_INUSE;
+    }
+
+    mappedMemory =
+        MapViewOfFile(memHandle,
+                      FILE_MAP_WRITE,       /* read/write */
+                      0, 0, 0);             /* map entire "file" */
+
+    if (mappedMemory == NULL) {
+        CloseHandle(memHandle);
+        memHandle = NULL;
+        return SYS_ERR;
+    }
+
+    *mem = memHandle;
+    *buffer = mappedMemory;
+    return SYS_OK;
+}
+
+int
+sysSharedMemOpen(const char *name, sys_shmem_t *mem, void **buffer)
+{
+    void *mappedMemory;
+    HANDLE memHandle;
+
+    sysAssert(name);
+    sysAssert(buffer);
+
+    memHandle =
+        OpenFileMapping(FILE_MAP_WRITE,     /* read/write */
+                        FALSE,              /* no inheritance */
+                        name);
+    if (memHandle == NULL) {
+        return SYS_ERR;
+    }
+
+    mappedMemory =
+        MapViewOfFile(memHandle,
+                      FILE_MAP_WRITE,       /* read/write */
+                      0, 0, 0);             /* map entire "file" */
+
+    if (mappedMemory == NULL) {
+        CloseHandle(memHandle);
+        memHandle = NULL;
+        return SYS_ERR;
+    }
+
+    *mem = memHandle;
+    *buffer = mappedMemory;
+    return SYS_OK;
+}
+
+int
+sysSharedMemClose(sys_shmem_t mem, void *buffer)
+{
+    if (buffer != NULL) {
+        if (!UnmapViewOfFile(buffer)) {
+            return SYS_ERR;
+        }
+    }
+
+    if (!CloseHandle(mem)) {
+        return SYS_ERR;
+    }
+
+    return SYS_OK;
+}
+
+int
+sysIPMutexCreate(const char *name, sys_ipmutex_t *mutexPtr)
+{
+    HANDLE mutex;
+
+    sysAssert(mutexPtr);
+    sysAssert(name);
+
+    mutex = CreateMutex(NULL,            /* no inheritance */
+                        FALSE,           /* no initial owner */
+                        name);
+    if (mutex == NULL) {
+        return SYS_ERR;
+    } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
+        /* If the call above didn't create it, consider it an error */
+        CloseHandle(mutex);
+        return SYS_INUSE;
+    }
+
+    *mutexPtr = mutex;
+    return SYS_OK;
+}
+
+int
+sysIPMutexOpen(const char *name, sys_ipmutex_t *mutexPtr)
+{
+    HANDLE mutex;
+
+    sysAssert(mutexPtr);
+    sysAssert(name);
+
+    mutex = OpenMutex(SYNCHRONIZE,      /* able to wait/release */
+                      FALSE,            /* no inheritance */
+                      name);
+    if (mutex == NULL) {
+        return SYS_ERR;
+    }
+
+    *mutexPtr = mutex;
+    return SYS_OK;
+}
+
+int
+sysIPMutexEnter(sys_ipmutex_t mutex, sys_event_t event)
+{
+    HANDLE handles[2] = { mutex, event };
+    int count = event == NULL ? 1 : 2;
+    DWORD rc;
+
+    sysAssert(mutex);
+    rc = WaitForMultipleObjects(count, handles,
+                                FALSE,              /* wait for either, not both */
+                                INFINITE);          /* infinite timeout */
+    return (rc == WAIT_OBJECT_0) ? SYS_OK : SYS_ERR;
+}
+
+int
+sysIPMutexExit(sys_ipmutex_t mutex)
+{
+    sysAssert(mutex);
+    return ReleaseMutex(mutex) ? SYS_OK : SYS_ERR;
+}
+
+int
+sysIPMutexClose(sys_ipmutex_t mutex)
+{
+    return CloseHandle(mutex) ? SYS_OK : SYS_ERR;
+}
+
+int
+sysEventCreate(const char *name, sys_event_t *eventPtr, jboolean manualReset)
+{
+    HANDLE event;
+    BOOL reset = (manualReset == JNI_TRUE) ? TRUE : FALSE;
+
+    sysAssert(eventPtr);
+
+    event = CreateEvent(NULL,            /* no inheritance */
+                        reset,           /* manual reset */
+                        FALSE,           /* initially, not signalled */
+                        name);
+    if (event == NULL) {
+        return SYS_ERR;
+    } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
+        /* If the call above didn't create it, consider it an error */
+        CloseHandle(event);
+        return SYS_INUSE;
+    }
+
+    *eventPtr = event;
+    return SYS_OK;
+}
+
+int
+sysEventOpen(const char *name, sys_event_t *eventPtr)
+{
+    HANDLE event;
+
+    sysAssert(eventPtr);
+    sysAssert(name);
+
+    event = OpenEvent(SYNCHRONIZE | EVENT_MODIFY_STATE,
+                                        /* able to wait/signal */
+                      FALSE,            /* no inheritance */
+                      name);
+    if (event == NULL) {
+        return SYS_ERR;
+    }
+
+    *eventPtr = event;
+    return SYS_OK;
+}
+
+int
+sysEventWait(sys_process_t otherProcess, sys_event_t event, long timeout)
+{
+    HANDLE handles[2];        /* process, event */
+    DWORD rc;
+    int count;
+    DWORD dwTimeout = (timeout == 0) ? INFINITE : (DWORD)timeout;
+
+    /*
+     * If the signalling process is specified, and it dies while we wait,
+     * detect it and return an error.
+     */
+    sysAssert(event);
+
+    handles[0] = event;
+    handles[1] = otherProcess;
+
+    count = (otherProcess == NULL) ? 1 : 2;
+
+    rc = WaitForMultipleObjects(count, handles,
+                                FALSE,        /* wait for either, not both */
+                                dwTimeout);
+    if (rc == WAIT_OBJECT_0) {
+        /* Signalled, return success */
+        return SYS_OK;
+    } else if (rc == WAIT_OBJECT_0 + 1) {
+        /* Other process died, return error */
+        return SYS_DIED;
+    } else if (rc == WAIT_TIMEOUT) {
+        /* timeout */
+        return SYS_TIMEOUT;
+    }
+    return SYS_ERR;
+}
+
+int
+sysEventSignal(sys_event_t event)
+{
+    sysAssert(event);
+    return SetEvent(event) ? SYS_OK : SYS_ERR;
+}
+
+int
+sysEventClose(sys_event_t event)
+{
+    return CloseHandle(event) ? SYS_OK : SYS_ERR;
+}
+
+jlong
+sysProcessGetID()
+{
+    return GetCurrentProcessId();
+}
+
+int
+sysProcessOpen(jlong processID, sys_process_t *processPtr)
+{
+    HANDLE process;
+
+    sysAssert(processPtr);
+
+    process = OpenProcess(SYNCHRONIZE,    /* able to wait on death */
+                          FALSE,          /* no inheritance */
+                          (DWORD)processID);
+    if (process == NULL) {
+        return SYS_ERR;
+    }
+
+    *processPtr = process;
+    return SYS_OK;
+}
+
+int
+sysProcessClose(sys_process_t *process)
+{
+    return CloseHandle(process) ? SYS_OK : SYS_ERR;
+}
+
+int
+sysGetLastError(char *buf, int len)
+{
+    long errval = GetLastError();
+    if (errval != 0) {
+        int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+                              NULL, errval,
+                              0, buf, len, NULL);
+        if (n > 3) {
+            /* Drop final '.', CR, LF */
+            if (buf[n - 1] == '\n') n--;
+            if (buf[n - 1] == '\r') n--;
+            if (buf[n - 1] == '.') n--;
+            buf[n] = '\0';
+        }
+        return SYS_OK;
+    }
+    buf[0] = '\0';
+    return 0;
+}
+
+int
+sysTlsAlloc() {
+    return TlsAlloc();
+}
+
+void
+sysTlsFree(int index) {
+    TlsFree(index);
+}
+
+void
+sysTlsPut(int index, void *value) {
+    TlsSetValue(index, value);
+}
+
+void *
+sysTlsGet(int index) {
+    return TlsGetValue(index);
+}
+
+void
+sysSleep(long duration) {
+    Sleep((DWORD)duration);
+}