jdk/src/windows/transport/shmem/shmem_md.c
author ohair
Tue, 11 Sep 2012 13:40:59 -0700
changeset 13678 5c8001201f98
parent 5506 202f599c92aa
child 14342 8435a30053c1
permissions -rw-r--r--
7197771: Adjust jdk sources to avoid use of implementation defined value of __FILE__ 7180608: Sort the order of object files when building shared libraries Reviewed-by: ohrstrom, erikj, tbell

/*
 * Copyright (c) 1999, 2003, 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);
}