1 /* 2 * Copyright (c) 1999, 2012, 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 /* 34 * These functions are not completely universal. For now, they are used 35 * exclusively for Jbug's shared memory transport mechanism. They have 36 * been implemented on Win32 only so far, so the abstractions may not be correct 37 * yet. 38 */ 39 40 static HANDLE memHandle = NULL; 41 42 #ifdef DEBUG 43 #define sysAssert(expression) { \ 44 if (!(expression)) { \ 45 exitTransportWithError \ 46 ("\"%s\", line %d: assertion failure\n", \ 47 __FILE__, __DATE__, __LINE__); \ 48 } \ 49 } 50 #else 51 #define sysAssert(expression) ((void) 0) 52 #endif 53 54 int 55 sysSharedMemCreate(const char *name, int length, 56 sys_shmem_t *mem, void **buffer) 57 { 58 void *mappedMemory; 59 HANDLE memHandle; 60 61 sysAssert(buffer); 62 sysAssert(name); 63 sysAssert(length > 0); 64 65 memHandle = 66 CreateFileMapping(INVALID_HANDLE_VALUE, /* backed by page file */ 67 NULL, /* no inheritance */ 68 PAGE_READWRITE, 69 0, length, /* hi, lo order of length */ 70 name); 71 if (memHandle == NULL) { 72 return SYS_ERR; 73 } else if (GetLastError() == ERROR_ALREADY_EXISTS) { 74 /* If the call above didn't create it, consider it an error */ 75 CloseHandle(memHandle); 76 memHandle = NULL; 77 return SYS_INUSE; 78 } 79 80 mappedMemory = 81 MapViewOfFile(memHandle, 82 FILE_MAP_WRITE, /* read/write */ 83 0, 0, 0); /* map entire "file" */ 84 85 if (mappedMemory == NULL) { 86 CloseHandle(memHandle); 87 memHandle = NULL; 88 return SYS_ERR; 89 } 90 91 *mem = memHandle; 92 *buffer = mappedMemory; 93 return SYS_OK; 94 } 95 96 int 97 sysSharedMemOpen(const char *name, sys_shmem_t *mem, void **buffer) 98 { 99 void *mappedMemory; 100 HANDLE memHandle; 101 102 sysAssert(name); 103 sysAssert(buffer); 104 105 memHandle = 106 OpenFileMapping(FILE_MAP_WRITE, /* read/write */ 107 FALSE, /* no inheritance */ 108 name); 109 if (memHandle == NULL) { 110 return SYS_ERR; 111 } 112 113 mappedMemory = 114 MapViewOfFile(memHandle, 115 FILE_MAP_WRITE, /* read/write */ 116 0, 0, 0); /* map entire "file" */ 117 118 if (mappedMemory == NULL) { 119 CloseHandle(memHandle); 120 memHandle = NULL; 121 return SYS_ERR; 122 } 123 124 *mem = memHandle; 125 *buffer = mappedMemory; 126 return SYS_OK; 127 } 128 129 int 130 sysSharedMemClose(sys_shmem_t mem, void *buffer) 131 { 132 if (buffer != NULL) { 133 if (!UnmapViewOfFile(buffer)) { 134 return SYS_ERR; 135 } 136 } 137 138 if (!CloseHandle(mem)) { 139 return SYS_ERR; 140 } 141 142 return SYS_OK; 143 } 144 145 int 146 sysIPMutexCreate(const char *name, sys_ipmutex_t *mutexPtr) 147 { 148 HANDLE mutex; 149 150 sysAssert(mutexPtr); 151 sysAssert(name); 152 153 mutex = CreateMutex(NULL, /* no inheritance */ 154 FALSE, /* no initial owner */ 155 name); 156 if (mutex == NULL) { 157 return SYS_ERR; 158 } else if (GetLastError() == ERROR_ALREADY_EXISTS) { 159 /* If the call above didn't create it, consider it an error */ 160 CloseHandle(mutex); 161 return SYS_INUSE; 162 } 163 164 *mutexPtr = mutex; 165 return SYS_OK; 166 } 167 168 int 169 sysIPMutexOpen(const char *name, sys_ipmutex_t *mutexPtr) 170 { 171 HANDLE mutex; 172 173 sysAssert(mutexPtr); 174 sysAssert(name); 175 176 mutex = OpenMutex(SYNCHRONIZE, /* able to wait/release */ 177 FALSE, /* no inheritance */ 178 name); 179 if (mutex == NULL) { 180 return SYS_ERR; 181 } 182 183 *mutexPtr = mutex; 184 return SYS_OK; 185 } 186 187 int 188 sysIPMutexEnter(sys_ipmutex_t mutex, sys_event_t event) 189 { 190 HANDLE handles[2] = { mutex, event }; 191 int count = event == NULL ? 1 : 2; 192 DWORD rc; 193 194 sysAssert(mutex); 195 rc = WaitForMultipleObjects(count, handles, 196 FALSE, /* wait for either, not both */ 197 INFINITE); /* infinite timeout */ 198 return (rc == WAIT_OBJECT_0) ? SYS_OK : SYS_ERR; 199 } 200 201 int 202 sysIPMutexExit(sys_ipmutex_t mutex) 203 { 204 sysAssert(mutex); 205 return ReleaseMutex(mutex) ? SYS_OK : SYS_ERR; 206 } 207 208 int 209 sysIPMutexClose(sys_ipmutex_t mutex) 210 { 211 return CloseHandle(mutex) ? SYS_OK : SYS_ERR; 212 } 213 214 int 215 sysEventCreate(const char *name, sys_event_t *eventPtr, jboolean manualReset) 216 { 217 HANDLE event; 218 BOOL reset = (manualReset == JNI_TRUE) ? TRUE : FALSE; 219 220 sysAssert(eventPtr); 221 222 event = CreateEvent(NULL, /* no inheritance */ 223 reset, /* manual reset */ 224 FALSE, /* initially, not signalled */ 225 name); 226 if (event == NULL) { 227 return SYS_ERR; 228 } else if (GetLastError() == ERROR_ALREADY_EXISTS) { 229 /* If the call above didn't create it, consider it an error */ 230 CloseHandle(event); 231 return SYS_INUSE; 232 } 233 234 *eventPtr = event; 235 return SYS_OK; 236 } 237 238 int 239 sysEventOpen(const char *name, sys_event_t *eventPtr) 240 { 241 HANDLE event; 242 243 sysAssert(eventPtr); 244 sysAssert(name); 245 246 event = OpenEvent(SYNCHRONIZE | EVENT_MODIFY_STATE, 247 /* able to wait/signal */ 248 FALSE, /* no inheritance */ 249 name); 250 if (event == NULL) { 251 return SYS_ERR; 252 } 253 254 *eventPtr = event; 255 return SYS_OK; 256 } 257 258 int 259 sysEventWait(sys_process_t otherProcess, sys_event_t event, long timeout) 260 { 261 HANDLE handles[2]; /* process, event */ 262 DWORD rc; 263 int count; 264 DWORD dwTimeout = (timeout == 0) ? INFINITE : (DWORD)timeout; 265 266 /* 267 * If the signalling process is specified, and it dies while we wait, 268 * detect it and return an error. 269 */ 270 sysAssert(event); 271 272 handles[0] = event; 273 handles[1] = otherProcess; 274 275 count = (otherProcess == NULL) ? 1 : 2; 276 277 rc = WaitForMultipleObjects(count, handles, 278 FALSE, /* wait for either, not both */ 279 dwTimeout); 280 if (rc == WAIT_OBJECT_0) { 281 /* Signalled, return success */ 282 return SYS_OK; 283 } else if (rc == WAIT_OBJECT_0 + 1) { 284 /* Other process died, return error */ 285 return SYS_DIED; 286 } else if (rc == WAIT_TIMEOUT) { 287 /* timeout */ 288 return SYS_TIMEOUT; 289 } 290 return SYS_ERR; 291 } 292 293 int 294 sysEventSignal(sys_event_t event) 295 { 296 sysAssert(event); 297 return SetEvent(event) ? SYS_OK : SYS_ERR; 298 } 299 300 int 301 sysEventClose(sys_event_t event) 302 { 303 return CloseHandle(event) ? SYS_OK : SYS_ERR; 304 } 305 306 jlong 307 sysProcessGetID() 308 { 309 return GetCurrentProcessId(); 310 } 311 312 int 313 sysProcessOpen(jlong processID, sys_process_t *processPtr) 314 { 315 HANDLE process; 316 317 sysAssert(processPtr); 318 319 process = OpenProcess(SYNCHRONIZE, /* able to wait on death */ 320 FALSE, /* no inheritance */ 321 (DWORD)processID); 322 if (process == NULL) { 323 return SYS_ERR; 324 } 325 326 *processPtr = process; 327 return SYS_OK; 328 } 329 330 int 331 sysProcessClose(sys_process_t *process) 332 { 333 return CloseHandle(process) ? SYS_OK : SYS_ERR; 334 } 335 336 int 337 sysGetLastError(char *buf, int len) 338 { 339 long errval = GetLastError(); 340 if (errval != 0) { 341 int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 342 NULL, errval, 343 0, buf, len, NULL); 344 if (n > 3) { 345 /* Drop final '.', CR, LF */ 346 if (buf[n - 1] == '\n') n--; 347 if (buf[n - 1] == '\r') n--; 348 if (buf[n - 1] == '.') n--; 349 buf[n] = '\0'; 350 } 351 return SYS_OK; 352 } 353 buf[0] = '\0'; 354 return 0; 355 } 356 357 int 358 sysTlsAlloc() { 359 return TlsAlloc(); 360 } 361 362 void 363 sysTlsFree(int index) { 364 TlsFree(index); 365 } 366 367 void 368 sysTlsPut(int index, void *value) { 369 TlsSetValue(index, value); 370 } 371 372 void * 373 sysTlsGet(int index) { 374 return TlsGetValue(index); 375 } 376 377 void 378 sysSleep(long duration) { 379 Sleep((DWORD)duration); 380 }