Changeset 101792 in vbox
- Timestamp:
- Nov 4, 2023 8:53:03 PM (15 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/nsprpub/pr/src/io/prpolevt.c
r1 r101792 58 58 #include "prerror.h" 59 59 #include "prlog.h" 60 61 #ifdef VMS62 63 /*64 * On OpenVMS we use an event flag instead of a pipe or a socket since65 * event flags are much more efficient on OpenVMS.66 */67 #include "pprio.h"68 #include <lib$routines.h>69 #include <starlet.h>70 #include <stsdef.h>71 72 PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)73 {74 unsigned int status;75 int flag = -1;76 PRFileDesc *event;77 78 /*79 ** Allocate an event flag and clear it.80 */81 status = lib$get_ef(&flag);82 if ((!$VMS_STATUS_SUCCESS(status)) || (flag == -1)) {83 PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, status);84 return NULL;85 }86 sys$clref(flag);87 88 /*89 ** Give NSPR the event flag's negative value. We do this because our90 ** select interprets a negative fd as an event flag rather than a91 ** regular file fd.92 */93 event = PR_CreateSocketPollFd(-flag);94 if (NULL == event) {95 lib$free_ef(&flag);96 return NULL;97 }98 99 return event;100 }101 102 PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)103 {104 int flag = -PR_FileDesc2NativeHandle(event);105 PR_DestroySocketPollFd(event);106 lib$free_ef(&flag);107 return PR_SUCCESS;108 }109 110 PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)111 {112 /*113 ** Just set the event flag.114 */115 unsigned int status;116 status = sys$setef(-PR_FileDesc2NativeHandle(event));117 if (!$VMS_STATUS_SUCCESS(status)) {118 PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);119 return PR_FAILURE;120 }121 return PR_SUCCESS;122 }123 124 PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)125 {126 /*127 ** Just clear the event flag.128 */129 unsigned int status;130 status = sys$clref(-PR_FileDesc2NativeHandle(event));131 if (!$VMS_STATUS_SUCCESS(status)) {132 PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);133 return PR_FAILURE;134 }135 return PR_SUCCESS;136 }137 138 #elif defined (XP_MAC)139 140 #include "primpl.h"141 142 /*143 * On Mac, local sockets cannot be used, because the networking stack144 * closes them when the machine goes to sleep. Instead, we'll use a simple145 * flag.146 */147 148 149 /*150 * PRFilePrivate structure for the NSPR pollable events layer151 */152 typedef struct PRPollableDesc {153 PRBool gotEvent;154 PRThread *pollingThread;155 } PRPollableDesc;156 157 static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd);158 159 static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(160 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);161 162 static PRIOMethods _pr_mac_polevt_methods = {163 PR_DESC_LAYERED,164 _pr_MacPolEvtClose,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,184 _pr_MacPolEvtPoll,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_InvalidInt199 };200 201 static PRDescIdentity _pr_mac_polevt_id;202 static PRCallOnceType _pr_mac_polevt_once_control;203 static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void);204 205 static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(206 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)207 {208 PRPollableDesc *pollDesc = (PRPollableDesc *)fd->secret;209 PR_ASSERT(pollDesc);210 211 // set the current thread so that we can wake up the poll thread212 pollDesc->pollingThread = PR_GetCurrentThread();213 214 if ((in_flags & PR_POLL_READ) && pollDesc->gotEvent)215 *out_flags = PR_POLL_READ;216 else217 *out_flags = 0;218 return pollDesc->gotEvent ? 1 : 0;219 }220 221 static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void)222 {223 _pr_mac_polevt_id = PR_GetUniqueIdentity("NSPR pollable events");224 if (PR_INVALID_IO_LAYER == _pr_mac_polevt_id) {225 return PR_FAILURE;226 }227 return PR_SUCCESS;228 }229 230 static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd)231 {232 PRPollableDesc *pollDesc = (PRPollableDesc *)fd->secret;233 PR_ASSERT(NULL == fd->higher && NULL == fd->lower);234 PR_ASSERT(pollDesc);235 PR_DELETE(pollDesc);236 fd->dtor(fd);237 return PR_SUCCESS;238 }239 240 PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)241 {242 PRFileDesc *event;243 PRPollableDesc *pollDesc;244 245 if (PR_CallOnce(&_pr_mac_polevt_once_control, _pr_MacPolEvtInit) == PR_FAILURE) {246 return NULL;247 }248 249 event = PR_CreateIOLayerStub(_pr_mac_polevt_id, &_pr_mac_polevt_methods);250 if (NULL == event) {251 return NULL;252 }253 254 /*255 ** Allocate an event flag and clear it.256 */257 pollDesc = PR_NEW(PRPollableDesc);258 if (!pollDesc) {259 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);260 goto errorExit;261 }262 263 pollDesc->gotEvent = PR_FALSE;264 pollDesc->pollingThread = NULL;265 266 event->secret = (PRFilePrivate*)pollDesc;267 return event;268 269 errorExit:270 271 if (event) {272 PR_DELETE(event->secret);273 event->dtor(event);274 }275 return NULL;276 }277 278 PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)279 {280 return PR_Close(event);281 }282 283 /* from macsockotpt.c. I wish there was a cleaner way */284 extern void WakeUpNotifiedThread(PRThread *thread, OTResult result);285 286 PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)287 {288 PRPollableDesc *pollDesc = (PRPollableDesc *)event->secret;289 PR_ASSERT(pollDesc);290 PR_ASSERT(pollDesc->pollingThread->state != _PR_DEAD_STATE);291 292 if (pollDesc->pollingThread->state == _PR_DEAD_STATE)293 return PR_FAILURE;294 295 pollDesc->gotEvent = PR_TRUE;296 297 if (pollDesc->pollingThread)298 WakeUpNotifiedThread(pollDesc->pollingThread, noErr);299 300 return PR_SUCCESS;301 }302 303 PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)304 {305 PRPollableDesc *pollDesc = (PRPollableDesc *)event->secret;306 PRStatus status;307 PR_ASSERT(pollDesc);308 309 /*310 FIXME: Danger Will Robinson!311 312 The current implementation of PR_WaitForPollableEvent is somewhat313 bogus; it makes the assumption that, in Mozilla, this will only314 ever be called when PR_Poll has returned, telling us that an315 event has been set.316 */317 318 PR_ASSERT(pollDesc->gotEvent);319 320 status = (pollDesc->gotEvent) ? PR_SUCCESS : PR_FAILURE;321 pollDesc->gotEvent = PR_FALSE;322 return status;323 }324 325 #else /* VMS */326 60 327 61 /* … … 407 141 } 408 142 409 #if !defined(XP_UNIX)410 #define USE_TCP_SOCKETPAIR411 #endif412 143 413 144 PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void) … … 415 146 PRFileDesc *event; 416 147 PRFileDesc *fd[2]; /* fd[0] is the read end; fd[1] is the write end */ 417 #ifdef USE_TCP_SOCKETPAIR418 PRSocketOptionData socket_opt;419 PRStatus rv;420 #endif421 148 422 149 fd[0] = fd[1] = NULL; … … 436 163 } 437 164 438 #ifndef USE_TCP_SOCKETPAIR439 165 if (PR_CreatePipe(&fd[0], &fd[1]) == PR_FAILURE) { 440 166 fd[0] = fd[1] = NULL; 441 167 goto errorExit; 442 168 } 443 #else 444 if (PR_NewTCPSocketPair(fd) == PR_FAILURE) { 445 fd[0] = fd[1] = NULL; 446 goto errorExit; 447 } 448 /* 449 * set the TCP_NODELAY option to reduce notification latency 450 */ 451 socket_opt.option = PR_SockOpt_NoDelay; 452 socket_opt.value.no_delay = PR_TRUE; 453 rv = PR_SetSocketOption(fd[1], &socket_opt); 454 PR_ASSERT(PR_SUCCESS == rv); 455 #endif 456 457 event->secret->writeEnd = fd[1]; 169 170 event->secret->writeEnd = fd[1]; 458 171 if (PR_PushIOLayer(fd[0], PR_TOP_IO_LAYER, event) == PR_FAILURE) { 459 172 goto errorExit; … … 528 241 } 529 242 530 #endif /* VMS */
Note:
See TracChangeset
for help on using the changeset viewer.