blob: 504e38e1e2a7758ebd9cab8c209d68dfc30316e8 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2003 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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
40static 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
54int
55sysSharedMemCreate(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
96int
97sysSharedMemOpen(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
129int
130sysSharedMemClose(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
145int
146sysIPMutexCreate(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
168int
169sysIPMutexOpen(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
187int
188sysIPMutexEnter(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
201int
202sysIPMutexExit(sys_ipmutex_t mutex)
203{
204 sysAssert(mutex);
205 return ReleaseMutex(mutex) ? SYS_OK : SYS_ERR;
206}
207
208int
209sysIPMutexClose(sys_ipmutex_t mutex)
210{
211 return CloseHandle(mutex) ? SYS_OK : SYS_ERR;
212}
213
214int
215sysEventCreate(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
238int
239sysEventOpen(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
258int
259sysEventWait(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
293int
294sysEventSignal(sys_event_t event)
295{
296 sysAssert(event);
297 return SetEvent(event) ? SYS_OK : SYS_ERR;
298}
299
300int
301sysEventClose(sys_event_t event)
302{
303 return CloseHandle(event) ? SYS_OK : SYS_ERR;
304}
305
306jlong
307sysProcessGetID()
308{
309 return GetCurrentProcessId();
310}
311
312int
313sysProcessOpen(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
330int
331sysProcessClose(sys_process_t *process)
332{
333 return CloseHandle(process) ? SYS_OK : SYS_ERR;
334}
335
336int
337sysGetLastError(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
357int
358sysTlsAlloc() {
359 return TlsAlloc();
360}
361
362void
363sysTlsFree(int index) {
364 TlsFree(index);
365}
366
367void
368sysTlsPut(int index, void *value) {
369 TlsSetValue(index, value);
370}
371
372void *
373sysTlsGet(int index) {
374 return TlsGetValue(index);
375}
376
377void
378sysSleep(long duration) {
379 Sleep((DWORD)duration);
380}