0N/A/*
3261N/A * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
0N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
2362N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2362N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
0N/A * or visit www.oracle.com if you need additional information or have any
0N/A * questions.
0N/A */
0N/A
0N/A#include <windows.h>
0N/A#include <errno.h>
0N/A
2156N/A#include "shmem_md.h"
2156N/A#include "sysShmem.h"
0N/A#include "shmemBase.h" /* for exitTransportWithError */
2156N/A
2156N/A/*
2156N/A * These functions are not completely universal. For now, they are used
0N/A * exclusively for Jbug's shared memory transport mechanism. They have
0N/A * been implemented on Win32 only so far, so the abstractions may not be correct
0N/A * yet.
0N/A */
0N/A
0N/Astatic HANDLE memHandle = NULL;
0N/A
0N/A#ifdef DEBUG
0N/A#define sysAssert(expression) { \
0N/A if (!(expression)) { \
0N/A exitTransportWithError \
0N/A ("\"%s\", line %d: assertion failure\n", \
0N/A __FILE__, __DATE__, __LINE__); \
0N/A } \
0N/A}
0N/A#else
0N/A#define sysAssert(expression) ((void) 0)
0N/A#endif
0N/A
0N/Aint
0N/AsysSharedMemCreate(const char *name, int length,
0N/A sys_shmem_t *mem, void **buffer)
2555N/A{
0N/A void *mappedMemory;
0N/A HANDLE memHandle;
0N/A
0N/A sysAssert(buffer);
0N/A sysAssert(name);
0N/A sysAssert(length > 0);
0N/A
0N/A memHandle =
0N/A CreateFileMapping(INVALID_HANDLE_VALUE, /* backed by page file */
0N/A NULL, /* no inheritance */
0N/A PAGE_READWRITE,
0N/A 0, length, /* hi, lo order of length */
0N/A name);
0N/A if (memHandle == NULL) {
0N/A return SYS_ERR;
0N/A } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
0N/A /* If the call above didn't create it, consider it an error */
0N/A CloseHandle(memHandle);
2555N/A memHandle = NULL;
2555N/A return SYS_INUSE;
0N/A }
0N/A
0N/A mappedMemory =
0N/A MapViewOfFile(memHandle,
0N/A FILE_MAP_WRITE, /* read/write */
0N/A 0, 0, 0); /* map entire "file" */
0N/A
0N/A if (mappedMemory == NULL) {
0N/A CloseHandle(memHandle);
0N/A memHandle = NULL;
0N/A return SYS_ERR;
0N/A }
0N/A
0N/A *mem = memHandle;
0N/A *buffer = mappedMemory;
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AsysSharedMemOpen(const char *name, sys_shmem_t *mem, void **buffer)
0N/A{
2555N/A void *mappedMemory;
0N/A HANDLE memHandle;
0N/A
0N/A sysAssert(name);
0N/A sysAssert(buffer);
0N/A
0N/A memHandle =
0N/A OpenFileMapping(FILE_MAP_WRITE, /* read/write */
0N/A FALSE, /* no inheritance */
0N/A name);
0N/A if (memHandle == NULL) {
0N/A return SYS_ERR;
0N/A }
0N/A
0N/A mappedMemory =
0N/A MapViewOfFile(memHandle,
0N/A FILE_MAP_WRITE, /* read/write */
0N/A 0, 0, 0); /* map entire "file" */
0N/A
0N/A if (mappedMemory == NULL) {
0N/A CloseHandle(memHandle);
0N/A memHandle = NULL;
0N/A return SYS_ERR;
0N/A }
0N/A
0N/A *mem = memHandle;
0N/A *buffer = mappedMemory;
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AsysSharedMemClose(sys_shmem_t mem, void *buffer)
0N/A{
0N/A if (buffer != NULL) {
0N/A if (!UnmapViewOfFile(buffer)) {
0N/A return SYS_ERR;
0N/A }
0N/A }
0N/A
0N/A if (!CloseHandle(mem)) {
0N/A return SYS_ERR;
0N/A }
0N/A
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AsysIPMutexCreate(const char *name, sys_ipmutex_t *mutexPtr)
0N/A{
0N/A HANDLE mutex;
0N/A
0N/A sysAssert(mutexPtr);
0N/A sysAssert(name);
0N/A
0N/A mutex = CreateMutex(NULL, /* no inheritance */
0N/A FALSE, /* no initial owner */
0N/A name);
0N/A if (mutex == NULL) {
0N/A return SYS_ERR;
0N/A } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
0N/A /* If the call above didn't create it, consider it an error */
0N/A CloseHandle(mutex);
0N/A return SYS_INUSE;
0N/A }
0N/A
0N/A *mutexPtr = mutex;
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AsysIPMutexOpen(const char *name, sys_ipmutex_t *mutexPtr)
0N/A{
0N/A HANDLE mutex;
0N/A
0N/A sysAssert(mutexPtr);
0N/A sysAssert(name);
0N/A
0N/A mutex = OpenMutex(SYNCHRONIZE, /* able to wait/release */
0N/A FALSE, /* no inheritance */
0N/A name);
0N/A if (mutex == NULL) {
0N/A return SYS_ERR;
0N/A }
0N/A
0N/A *mutexPtr = mutex;
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AsysIPMutexEnter(sys_ipmutex_t mutex, sys_event_t event)
0N/A{
0N/A HANDLE handles[2] = { mutex, event };
0N/A int count = event == NULL ? 1 : 2;
0N/A DWORD rc;
0N/A
0N/A sysAssert(mutex);
0N/A rc = WaitForMultipleObjects(count, handles,
0N/A FALSE, /* wait for either, not both */
0N/A INFINITE); /* infinite timeout */
0N/A return (rc == WAIT_OBJECT_0) ? SYS_OK : SYS_ERR;
0N/A}
0N/A
0N/Aint
0N/AsysIPMutexExit(sys_ipmutex_t mutex)
0N/A{
0N/A sysAssert(mutex);
0N/A return ReleaseMutex(mutex) ? SYS_OK : SYS_ERR;
0N/A}
0N/A
0N/Aint
0N/AsysIPMutexClose(sys_ipmutex_t mutex)
0N/A{
0N/A return CloseHandle(mutex) ? SYS_OK : SYS_ERR;
0N/A}
0N/A
0N/Aint
0N/AsysEventCreate(const char *name, sys_event_t *eventPtr, jboolean manualReset)
0N/A{
0N/A HANDLE event;
0N/A BOOL reset = (manualReset == JNI_TRUE) ? TRUE : FALSE;
0N/A
0N/A sysAssert(eventPtr);
0N/A
0N/A event = CreateEvent(NULL, /* no inheritance */
0N/A reset, /* manual reset */
0N/A FALSE, /* initially, not signalled */
0N/A name);
0N/A if (event == NULL) {
0N/A return SYS_ERR;
0N/A } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
0N/A /* If the call above didn't create it, consider it an error */
0N/A CloseHandle(event);
0N/A return SYS_INUSE;
0N/A }
0N/A
0N/A *eventPtr = event;
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AsysEventOpen(const char *name, sys_event_t *eventPtr)
0N/A{
0N/A HANDLE event;
0N/A
0N/A sysAssert(eventPtr);
0N/A sysAssert(name);
0N/A
0N/A event = OpenEvent(SYNCHRONIZE | EVENT_MODIFY_STATE,
0N/A /* able to wait/signal */
0N/A FALSE, /* no inheritance */
0N/A name);
0N/A if (event == NULL) {
0N/A return SYS_ERR;
0N/A }
0N/A
0N/A *eventPtr = event;
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AsysEventWait(sys_process_t otherProcess, sys_event_t event, long timeout)
0N/A{
0N/A HANDLE handles[2]; /* process, event */
0N/A DWORD rc;
0N/A int count;
0N/A DWORD dwTimeout = (timeout == 0) ? INFINITE : (DWORD)timeout;
0N/A
0N/A /*
0N/A * If the signalling process is specified, and it dies while we wait,
0N/A * detect it and return an error.
0N/A */
0N/A sysAssert(event);
0N/A
0N/A handles[0] = event;
0N/A handles[1] = otherProcess;
0N/A
0N/A count = (otherProcess == NULL) ? 1 : 2;
0N/A
0N/A rc = WaitForMultipleObjects(count, handles,
0N/A FALSE, /* wait for either, not both */
0N/A dwTimeout);
0N/A if (rc == WAIT_OBJECT_0) {
0N/A /* Signalled, return success */
0N/A return SYS_OK;
0N/A } else if (rc == WAIT_OBJECT_0 + 1) {
0N/A /* Other process died, return error */
0N/A return SYS_DIED;
0N/A } else if (rc == WAIT_TIMEOUT) {
0N/A /* timeout */
0N/A return SYS_TIMEOUT;
0N/A }
0N/A return SYS_ERR;
0N/A}
0N/A
0N/Aint
0N/AsysEventSignal(sys_event_t event)
0N/A{
0N/A sysAssert(event);
0N/A return SetEvent(event) ? SYS_OK : SYS_ERR;
0N/A}
0N/A
0N/Aint
0N/AsysEventClose(sys_event_t event)
0N/A{
0N/A return CloseHandle(event) ? SYS_OK : SYS_ERR;
0N/A}
0N/A
0N/Ajlong
0N/AsysProcessGetID()
0N/A{
0N/A return GetCurrentProcessId();
0N/A}
0N/A
0N/Aint
0N/AsysProcessOpen(jlong processID, sys_process_t *processPtr)
0N/A{
0N/A HANDLE process;
0N/A
0N/A sysAssert(processPtr);
0N/A
0N/A process = OpenProcess(SYNCHRONIZE, /* able to wait on death */
0N/A FALSE, /* no inheritance */
0N/A (DWORD)processID);
0N/A if (process == NULL) {
0N/A return SYS_ERR;
0N/A }
0N/A
0N/A *processPtr = process;
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AsysProcessClose(sys_process_t *process)
0N/A{
0N/A return CloseHandle(process) ? SYS_OK : SYS_ERR;
0N/A}
0N/A
0N/Aint
0N/AsysGetLastError(char *buf, int len)
0N/A{
0N/A long errval = GetLastError();
0N/A if (errval != 0) {
0N/A int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
0N/A NULL, errval,
0N/A 0, buf, len, NULL);
0N/A if (n > 3) {
0N/A /* Drop final '.', CR, LF */
0N/A if (buf[n - 1] == '\n') n--;
0N/A if (buf[n - 1] == '\r') n--;
0N/A if (buf[n - 1] == '.') n--;
0N/A buf[n] = '\0';
0N/A }
0N/A return SYS_OK;
0N/A }
0N/A buf[0] = '\0';
0N/A return 0;
0N/A}
0N/A
0N/Aint
0N/AsysTlsAlloc() {
0N/A return TlsAlloc();
0N/A}
0N/A
0N/Avoid
0N/AsysTlsFree(int index) {
0N/A TlsFree(index);
0N/A}
0N/A
0N/Avoid
0N/AsysTlsPut(int index, void *value) {
0N/A TlsSetValue(index, value);
0N/A}
0N/A
0N/Avoid *
0N/AsysTlsGet(int index) {
0N/A return TlsGetValue(index);
0N/A}
0N/A
0N/Avoid
0N/AsysSleep(long duration) {
0N/A Sleep((DWORD)duration);
0N/A}
0N/A