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 }