58
58
#include "prerror.h"
64
* On OpenVMS we use an event flag instead of a pipe or a socket since
65
* event flags are much more efficient on OpenVMS.
68
#include <lib$routines.h>
72
PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
79
** Allocate an event flag and clear it.
81
status = lib$get_ef(&flag);
82
if ((!$VMS_STATUS_SUCCESS(status)) || (flag == -1)) {
83
PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, status);
89
** Give NSPR the event flag's negative value. We do this because our
90
** select interprets a negative fd as an event flag rather than a
93
event = PR_CreateSocketPollFd(-flag);
102
PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
104
int flag = -PR_FileDesc2NativeHandle(event);
105
PR_DestroySocketPollFd(event);
110
PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
113
** Just set the event flag.
116
status = sys$setef(-PR_FileDesc2NativeHandle(event));
117
if (!$VMS_STATUS_SUCCESS(status)) {
118
PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);
124
PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
127
** Just clear the event flag.
130
status = sys$clref(-PR_FileDesc2NativeHandle(event));
131
if (!$VMS_STATUS_SUCCESS(status)) {
132
PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);
138
#elif defined (XP_MAC)
143
* On Mac, local sockets cannot be used, because the networking stack
144
* closes them when the machine goes to sleep. Instead, we'll use a simple
150
* PRFilePrivate structure for the NSPR pollable events layer
152
typedef struct PRPollableDesc {
154
PRThread *pollingThread;
157
static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd);
159
static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
160
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
162
static PRIOMethods _pr_mac_polevt_methods = {
165
(PRReadFN)_PR_InvalidInt,
166
(PRWriteFN)_PR_InvalidInt,
167
(PRAvailableFN)_PR_InvalidInt,
168
(PRAvailable64FN)_PR_InvalidInt64,
169
(PRFsyncFN)_PR_InvalidStatus,
170
(PRSeekFN)_PR_InvalidInt,
171
(PRSeek64FN)_PR_InvalidInt64,
172
(PRFileInfoFN)_PR_InvalidStatus,
173
(PRFileInfo64FN)_PR_InvalidStatus,
174
(PRWritevFN)_PR_InvalidInt,
175
(PRConnectFN)_PR_InvalidStatus,
176
(PRAcceptFN)_PR_InvalidDesc,
177
(PRBindFN)_PR_InvalidStatus,
178
(PRListenFN)_PR_InvalidStatus,
179
(PRShutdownFN)_PR_InvalidStatus,
180
(PRRecvFN)_PR_InvalidInt,
181
(PRSendFN)_PR_InvalidInt,
182
(PRRecvfromFN)_PR_InvalidInt,
183
(PRSendtoFN)_PR_InvalidInt,
185
(PRAcceptreadFN)_PR_InvalidInt,
186
(PRTransmitfileFN)_PR_InvalidInt,
187
(PRGetsocknameFN)_PR_InvalidStatus,
188
(PRGetpeernameFN)_PR_InvalidStatus,
189
(PRReservedFN)_PR_InvalidInt,
190
(PRReservedFN)_PR_InvalidInt,
191
(PRGetsocketoptionFN)_PR_InvalidStatus,
192
(PRSetsocketoptionFN)_PR_InvalidStatus,
193
(PRSendfileFN)_PR_InvalidInt,
194
(PRConnectcontinueFN)_PR_InvalidStatus,
195
(PRReservedFN)_PR_InvalidInt,
196
(PRReservedFN)_PR_InvalidInt,
197
(PRReservedFN)_PR_InvalidInt,
198
(PRReservedFN)_PR_InvalidInt
201
static PRDescIdentity _pr_mac_polevt_id;
202
static PRCallOnceType _pr_mac_polevt_once_control;
203
static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void);
205
static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
206
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
208
PRPollableDesc *pollDesc = (PRPollableDesc *)fd->secret;
211
// set the current thread so that we can wake up the poll thread
212
pollDesc->pollingThread = PR_GetCurrentThread();
214
if ((in_flags & PR_POLL_READ) && pollDesc->gotEvent)
215
*out_flags = PR_POLL_READ;
218
return pollDesc->gotEvent ? 1 : 0;
221
static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void)
223
_pr_mac_polevt_id = PR_GetUniqueIdentity("NSPR pollable events");
224
if (PR_INVALID_IO_LAYER == _pr_mac_polevt_id) {
230
static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd)
232
PRPollableDesc *pollDesc = (PRPollableDesc *)fd->secret;
233
PR_ASSERT(NULL == fd->higher && NULL == fd->lower);
240
PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
243
PRPollableDesc *pollDesc;
245
if (PR_CallOnce(&_pr_mac_polevt_once_control, _pr_MacPolEvtInit) == PR_FAILURE) {
249
event = PR_CreateIOLayerStub(_pr_mac_polevt_id, &_pr_mac_polevt_methods);
255
** Allocate an event flag and clear it.
257
pollDesc = PR_NEW(PRPollableDesc);
259
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
263
pollDesc->gotEvent = PR_FALSE;
264
pollDesc->pollingThread = NULL;
266
event->secret = (PRFilePrivate*)pollDesc;
272
PR_DELETE(event->secret);
278
PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
280
return PR_Close(event);
283
/* from macsockotpt.c. I wish there was a cleaner way */
284
extern void WakeUpNotifiedThread(PRThread *thread, OTResult result);
286
PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
288
PRPollableDesc *pollDesc = (PRPollableDesc *)event->secret;
290
PR_ASSERT(pollDesc->pollingThread->state != _PR_DEAD_STATE);
292
if (pollDesc->pollingThread->state == _PR_DEAD_STATE)
295
pollDesc->gotEvent = PR_TRUE;
297
if (pollDesc->pollingThread)
298
WakeUpNotifiedThread(pollDesc->pollingThread, noErr);
303
PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
305
PRPollableDesc *pollDesc = (PRPollableDesc *)event->secret;
310
FIXME: Danger Will Robinson!
312
The current implementation of PR_WaitForPollableEvent is somewhat
313
bogus; it makes the assumption that, in Mozilla, this will only
314
ever be called when PR_Poll has returned, telling us that an
318
PR_ASSERT(pollDesc->gotEvent);
320
status = (pollDesc->gotEvent) ? PR_SUCCESS : PR_FAILURE;
321
pollDesc->gotEvent = PR_FALSE;
328
62
* These internal functions are declared in primpl.h,
329
63
* but we can't include primpl.h because the definition