1 /*
   2  * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <windows.h>
  27 #include <errno.h>
  28 
  29 #include "shmem_md.h"
  30 #include "sysShmem.h"
  31 #include "shmemBase.h"  /* for exitTransportWithError */
  32 
  33 /* Use THIS_FILE when it is available. */
  34 #ifndef THIS_FILE
  35     #define THIS_FILE __FILE__
  36 #endif
  37 
  38 /*
  39  * These functions are not completely universal. For now, they are used
  40  * exclusively for Jbug's shared memory transport mechanism. They have
  41  * been implemented on Win32 only so far, so the abstractions may not be correct
  42  * yet.
  43  */
  44 
  45 static HANDLE memHandle = NULL;
  46 
  47 #ifdef DEBUG
  48 #define sysAssert(expression) {         \
  49     if (!(expression)) {                \
  50             exitTransportWithError \
  51             ("\"%s\", line %d: assertion failure\n", \
  52              THIS_FILE, __DATE__, __LINE__); \
  53     }                                   \
  54 }
  55 #else
  56 #define sysAssert(expression) ((void) 0)
  57 #endif
  58 
  59 int
  60 sysSharedMemCreate(const char *name, int length,
  61                    sys_shmem_t *mem, void **buffer)
  62 {
  63     void *mappedMemory;
  64     HANDLE memHandle;
  65 
  66     sysAssert(buffer);
  67     sysAssert(name);
  68     sysAssert(length > 0);
  69 
  70     memHandle  =
  71         CreateFileMapping(INVALID_HANDLE_VALUE, /* backed by page file */
  72                           NULL,               /* no inheritance */
  73                           PAGE_READWRITE,
  74                           0, length,          /* hi, lo order of length */
  75                           name);
  76     if (memHandle == NULL) {
  77         return SYS_ERR;
  78     } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
  79         /* If the call above didn't create it, consider it an error */
  80         CloseHandle(memHandle);
  81         memHandle = NULL;
  82         return SYS_INUSE;
  83     }
  84 
  85     mappedMemory =
  86         MapViewOfFile(memHandle,
  87                       FILE_MAP_WRITE,       /* read/write */
  88                       0, 0, 0);             /* map entire "file" */
  89 
  90     if (mappedMemory == NULL) {
  91         CloseHandle(memHandle);
  92         memHandle = NULL;
  93         return SYS_ERR;
  94     }
  95 
  96     *mem = memHandle;
  97     *buffer = mappedMemory;
  98     return SYS_OK;
  99 }
 100 
 101 int
 102 sysSharedMemOpen(const char *name, sys_shmem_t *mem, void **buffer)
 103 {
 104     void *mappedMemory;
 105     HANDLE memHandle;
 106 
 107     sysAssert(name);
 108     sysAssert(buffer);
 109 
 110     memHandle =
 111         OpenFileMapping(FILE_MAP_WRITE,     /* read/write */
 112                         FALSE,              /* no inheritance */
 113                         name);
 114     if (memHandle == NULL) {
 115         return SYS_ERR;
 116     }
 117 
 118     mappedMemory =
 119         MapViewOfFile(memHandle,
 120                       FILE_MAP_WRITE,       /* read/write */
 121                       0, 0, 0);             /* map entire "file" */
 122 
 123     if (mappedMemory == NULL) {
 124         CloseHandle(memHandle);
 125         memHandle = NULL;
 126         return SYS_ERR;
 127     }
 128 
 129     *mem = memHandle;
 130     *buffer = mappedMemory;
 131     return SYS_OK;
 132 }
 133 
 134 int
 135 sysSharedMemClose(sys_shmem_t mem, void *buffer)
 136 {
 137     if (buffer != NULL) {
 138         if (!UnmapViewOfFile(buffer)) {
 139             return SYS_ERR;
 140         }
 141     }
 142 
 143     if (!CloseHandle(mem)) {
 144         return SYS_ERR;
 145     }
 146 
 147     return SYS_OK;
 148 }
 149 
 150 int
 151 sysIPMutexCreate(const char *name, sys_ipmutex_t *mutexPtr)
 152 {
 153     HANDLE mutex;
 154 
 155     sysAssert(mutexPtr);
 156     sysAssert(name);
 157 
 158     mutex = CreateMutex(NULL,            /* no inheritance */
 159                         FALSE,           /* no initial owner */
 160                         name);
 161     if (mutex == NULL) {
 162         return SYS_ERR;
 163     } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
 164         /* If the call above didn't create it, consider it an error */
 165         CloseHandle(mutex);
 166         return SYS_INUSE;
 167     }
 168 
 169     *mutexPtr = mutex;
 170     return SYS_OK;
 171 }
 172 
 173 int
 174 sysIPMutexOpen(const char *name, sys_ipmutex_t *mutexPtr)
 175 {
 176     HANDLE mutex;
 177 
 178     sysAssert(mutexPtr);
 179     sysAssert(name);
 180 
 181     mutex = OpenMutex(SYNCHRONIZE,      /* able to wait/release */
 182                       FALSE,            /* no inheritance */
 183                       name);
 184     if (mutex == NULL) {
 185         return SYS_ERR;
 186     }
 187 
 188     *mutexPtr = mutex;
 189     return SYS_OK;
 190 }
 191 
 192 int
 193 sysIPMutexEnter(sys_ipmutex_t mutex, sys_event_t event)
 194 {
 195     HANDLE handles[2] = { mutex, event };
 196     int count = event == NULL ? 1 : 2;
 197     DWORD rc;
 198 
 199     sysAssert(mutex);
 200     rc = WaitForMultipleObjects(count, handles,
 201                                 FALSE,              /* wait for either, not both */
 202                                 INFINITE);          /* infinite timeout */
 203     return (rc == WAIT_OBJECT_0) ? SYS_OK : SYS_ERR;
 204 }
 205 
 206 int
 207 sysIPMutexExit(sys_ipmutex_t mutex)
 208 {
 209     sysAssert(mutex);
 210     return ReleaseMutex(mutex) ? SYS_OK : SYS_ERR;
 211 }
 212 
 213 int
 214 sysIPMutexClose(sys_ipmutex_t mutex)
 215 {
 216     return CloseHandle(mutex) ? SYS_OK : SYS_ERR;
 217 }
 218 
 219 int
 220 sysEventCreate(const char *name, sys_event_t *eventPtr, jboolean manualReset)
 221 {
 222     HANDLE event;
 223     BOOL reset = (manualReset == JNI_TRUE) ? TRUE : FALSE;
 224 
 225     sysAssert(eventPtr);
 226 
 227     event = CreateEvent(NULL,            /* no inheritance */
 228                         reset,           /* manual reset */
 229                         FALSE,           /* initially, not signalled */
 230                         name);
 231     if (event == NULL) {
 232         return SYS_ERR;
 233     } else if (GetLastError() == ERROR_ALREADY_EXISTS) {
 234         /* If the call above didn't create it, consider it an error */
 235         CloseHandle(event);
 236         return SYS_INUSE;
 237     }
 238 
 239     *eventPtr = event;
 240     return SYS_OK;
 241 }
 242 
 243 int
 244 sysEventOpen(const char *name, sys_event_t *eventPtr)
 245 {
 246     HANDLE event;
 247 
 248     sysAssert(eventPtr);
 249     sysAssert(name);
 250 
 251     event = OpenEvent(SYNCHRONIZE | EVENT_MODIFY_STATE,
 252                                         /* able to wait/signal */
 253                       FALSE,            /* no inheritance */
 254                       name);
 255     if (event == NULL) {
 256         return SYS_ERR;
 257     }
 258 
 259     *eventPtr = event;
 260     return SYS_OK;
 261 }
 262 
 263 int
 264 sysEventWait(sys_process_t otherProcess, sys_event_t event, long timeout)
 265 {
 266     HANDLE handles[2];        /* process, event */
 267     DWORD rc;
 268     int count;
 269     DWORD dwTimeout = (timeout == 0) ? INFINITE : (DWORD)timeout;
 270 
 271     /*
 272      * If the signalling process is specified, and it dies while we wait,
 273      * detect it and return an error.
 274      */
 275     sysAssert(event);
 276 
 277     handles[0] = event;
 278     handles[1] = otherProcess;
 279 
 280     count = (otherProcess == NULL) ? 1 : 2;
 281 
 282     rc = WaitForMultipleObjects(count, handles,
 283                                 FALSE,        /* wait for either, not both */
 284                                 dwTimeout);
 285     if (rc == WAIT_OBJECT_0) {
 286         /* Signalled, return success */
 287         return SYS_OK;
 288     } else if (rc == WAIT_OBJECT_0 + 1) {
 289         /* Other process died, return error */
 290         return SYS_DIED;
 291     } else if (rc == WAIT_TIMEOUT) {
 292         /* timeout */
 293         return SYS_TIMEOUT;
 294     }
 295     return SYS_ERR;
 296 }
 297 
 298 int
 299 sysEventSignal(sys_event_t event)
 300 {
 301     sysAssert(event);
 302     return SetEvent(event) ? SYS_OK : SYS_ERR;
 303 }
 304 
 305 int
 306 sysEventClose(sys_event_t event)
 307 {
 308     return CloseHandle(event) ? SYS_OK : SYS_ERR;
 309 }
 310 
 311 jlong
 312 sysProcessGetID()
 313 {
 314     return GetCurrentProcessId();
 315 }
 316 
 317 int
 318 sysProcessOpen(jlong processID, sys_process_t *processPtr)
 319 {
 320     HANDLE process;
 321 
 322     sysAssert(processPtr);
 323 
 324     process = OpenProcess(SYNCHRONIZE,    /* able to wait on death */
 325                           FALSE,          /* no inheritance */
 326                           (DWORD)processID);
 327     if (process == NULL) {
 328         return SYS_ERR;
 329     }
 330 
 331     *processPtr = process;
 332     return SYS_OK;
 333 }
 334 
 335 int
 336 sysProcessClose(sys_process_t *process)
 337 {
 338     return CloseHandle(process) ? SYS_OK : SYS_ERR;
 339 }
 340 
 341 int
 342 sysGetLastError(char *buf, int len)
 343 {
 344     long errval = GetLastError();
 345     if (errval != 0) {
 346         int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
 347                               NULL, errval,
 348                               0, buf, len, NULL);
 349         if (n > 3) {
 350             /* Drop final '.', CR, LF */
 351             if (buf[n - 1] == '\n') n--;
 352             if (buf[n - 1] == '\r') n--;
 353             if (buf[n - 1] == '.') n--;
 354             buf[n] = '\0';
 355         }
 356         return SYS_OK;
 357     }
 358     buf[0] = '\0';
 359     return 0;
 360 }
 361 
 362 int
 363 sysTlsAlloc() {
 364     return TlsAlloc();
 365 }
 366 
 367 void
 368 sysTlsFree(int index) {
 369     TlsFree(index);
 370 }
 371 
 372 void
 373 sysTlsPut(int index, void *value) {
 374     TlsSetValue(index, value);
 375 }
 376 
 377 void *
 378 sysTlsGet(int index) {
 379     return TlsGetValue(index);
 380 }
 381 
 382 void
 383 sysSleep(long duration) {
 384     Sleep((DWORD)duration);
 385 }