Changeset 101888 in vbox
- Timestamp:
- Nov 6, 2023 6:33:11 PM (15 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcConnectionUnix.cpp
r101885 r101888 51 51 # include <iprt/env.h> 52 52 # include <iprt/log.h> 53 # include <iprt/mem.h> 54 # include <iprt/pipe.h> 55 # include <iprt/string.h> 53 56 # include <iprt/thread.h> 54 57 … … 116 119 //----------------------------------------------------------------------------- 117 120 121 /* Character written for wakeup. */ 122 static const char magicChar = '\x38'; 123 118 124 struct ipcCallback : public ipcListNode<ipcCallback> 119 125 { … … 129 135 { 130 136 RTCRITSECT CritSect; 137 RTPIPE hWakeupPipeW; 131 138 PRPollDesc fds[2]; 132 139 ipcCallbackQ callback_queue; … … 155 162 156 163 s->send_queue.DeleteAll(); 157 delete s;164 RTMemFree(s); 158 165 } 159 166 160 167 static ipcConnectionState *ConnCreate(PRFileDesc *fd) 161 168 { 162 ipcConnectionState *s = new ipcConnectionState; 163 if (!s) 169 ipcConnectionState *s = (ipcConnectionState *)RTMemAllocZ(sizeof(*s)); 170 if (!s) 171 return NULL; 172 173 int vrc = RTCritSectInit(&s->CritSect); 174 if (RT_SUCCESS(vrc)) 175 { 176 RTPIPE hPipeR; 177 178 vrc = RTPipeCreate(&hPipeR, &s->hWakeupPipeW, 0 /*fFlags*/); 179 if (RT_SUCCESS(vrc)) 180 { 181 s->fds[SOCK].fd = NULL; 182 s->fds[POLL].fd = PR_AllocFileDesc((PRInt32)RTPipeToNative(hPipeR), PR_GetPipeMethods()); 183 s->send_offset = 0; 184 s->in_msg = NULL; 185 s->shutdown = PR_FALSE; 186 187 if (s->fds[POLL].fd) 188 { 189 /* NSPR has taken over the pipe. */ 190 vrc = RTPipeCloseEx(hPipeR, true /*fLeaveOpen*/); AssertRC(vrc); 191 192 // disable inheritance of the IPC socket by children started 193 // using non-NSPR process API 194 PRStatus status = PR_SetFDInheritable(fd, PR_FALSE); 195 if (status == PR_SUCCESS) 196 { 197 // store this only if we are going to succeed. 198 s->fds[SOCK].fd = fd; 199 200 return s; 201 } 202 203 PR_Close(s->fds[POLL].fd); 204 s->fds[POLL].fd = NULL; 205 LOG(("coudn't make IPC socket non-inheritable [err=%d]\n", PR_GetError())); 206 } 207 208 vrc = RTPipeClose(hPipeR); AssertRC(vrc); 209 vrc = RTPipeClose(s->hWakeupPipeW); AssertRC(vrc); 210 } 211 212 ConnDestroy(s); 213 } 214 164 215 return NULL; 165 166 int vrc = RTCritSectInit(&s->CritSect);167 if (RT_FAILURE(vrc))168 {169 ConnDestroy(s);170 return NULL;171 }172 173 s->fds[SOCK].fd = NULL;174 s->fds[POLL].fd = PR_NewPollableEvent();175 s->send_offset = 0;176 s->in_msg = NULL;177 s->shutdown = PR_FALSE;178 179 if (!s->fds[1].fd)180 {181 ConnDestroy(s);182 return NULL;183 }184 185 // disable inheritance of the IPC socket by children started186 // using non-NSPR process API187 PRStatus status = PR_SetFDInheritable(fd, PR_FALSE);188 if (status != PR_SUCCESS)189 {190 LOG(("coudn't make IPC socket non-inheritable [err=%d]\n", PR_GetError()));191 return NULL;192 }193 194 // store this only if we are going to succeed.195 s->fds[SOCK].fd = fd;196 197 return s;198 216 } 199 217 … … 350 368 if (s->fds[POLL].out_flags & PR_POLL_READ) 351 369 { 352 PR_WaitForPollableEvent(s->fds[POLL].fd); 370 /* Drain wakeup pipe. */ 371 uint8_t buf[32]; 372 #ifdef DEBUG 373 PRIntn i; 374 #endif 375 PRInt32 nBytes = PR_Read(s->fds[POLL].fd, buf, sizeof(buf)); 376 Assert(nBytes > 0); 377 378 #ifdef DEBUG 379 /* Make sure this is not written with something else. */ 380 for (i = 0; i < nBytes; i++) { 381 Assert(buf[i] == magicChar); 382 } 383 #endif 384 353 385 RTCritSectEnter(&s->CritSect); 354 386 … … 533 565 IPC_Disconnect() 534 566 { 535 // Must disconnect on same thread used to connect! 536 Assert(gMainThread == RTThreadSelf()); 537 538 if (!gConnState || !gConnThread) 539 return NS_ERROR_NOT_INITIALIZED; 540 541 RTCritSectEnter(&gConnState->CritSect); 542 gConnState->shutdown = PR_TRUE; 543 PR_SetPollableEvent(gConnState->fds[POLL].fd); 544 RTCritSectLeave(&gConnState->CritSect); 545 546 int rcThread; 547 RTThreadWait(gConnThread, RT_INDEFINITE_WAIT, &rcThread); 548 AssertRC(rcThread); 549 550 ConnDestroy(gConnState); 551 552 gConnState = NULL; 553 gConnThread = NULL; 554 return NS_OK; 567 // Must disconnect on same thread used to connect! 568 Assert(gMainThread == RTThreadSelf()); 569 570 if (!gConnState || !gConnThread) 571 return NS_ERROR_NOT_INITIALIZED; 572 573 RTCritSectEnter(&gConnState->CritSect); 574 gConnState->shutdown = PR_TRUE; 575 size_t cbWrittenIgn = 0; 576 int vrc = RTPipeWrite(gConnState->hWakeupPipeW, &magicChar, sizeof(magicChar), &cbWrittenIgn); 577 AssertRC(vrc); 578 RTCritSectLeave(&gConnState->CritSect); 579 580 int rcThread; 581 RTThreadWait(gConnThread, RT_INDEFINITE_WAIT, &rcThread); 582 AssertRC(rcThread); 583 584 ConnDestroy(gConnState); 585 586 gConnState = NULL; 587 gConnThread = NULL; 588 return NS_OK; 555 589 } 556 590 … … 558 592 IPC_SendMsg(ipcMessage *msg) 559 593 { 560 if (!gConnState || !gConnThread) 561 return NS_ERROR_NOT_INITIALIZED; 562 563 RTCritSectEnter(&gConnState->CritSect); 564 gConnState->send_queue.Append(msg); 565 PR_SetPollableEvent(gConnState->fds[POLL].fd); 566 RTCritSectLeave(&gConnState->CritSect); 567 568 return NS_OK; 594 if (!gConnState || !gConnThread) 595 return NS_ERROR_NOT_INITIALIZED; 596 597 RTCritSectEnter(&gConnState->CritSect); 598 gConnState->send_queue.Append(msg); 599 size_t cbWrittenIgn = 0; 600 int vrc = RTPipeWrite(gConnState->hWakeupPipeW, &magicChar, sizeof(magicChar), &cbWrittenIgn); 601 AssertRC(vrc); 602 RTCritSectLeave(&gConnState->CritSect); 603 604 return NS_OK; 569 605 } 570 606 … … 572 608 IPC_DoCallback(ipcCallbackFunc func, void *arg) 573 609 { 574 if (!gConnState || !gConnThread) 575 return NS_ERROR_NOT_INITIALIZED; 576 577 ipcCallback *callback = new ipcCallback; 578 if (!callback) 579 return NS_ERROR_OUT_OF_MEMORY; 580 callback->func = func; 581 callback->arg = arg; 582 583 RTCritSectEnter(&gConnState->CritSect); 584 gConnState->callback_queue.Append(callback); 585 PR_SetPollableEvent(gConnState->fds[POLL].fd); 586 RTCritSectLeave(&gConnState->CritSect); 587 return NS_OK; 588 } 589 610 if (!gConnState || !gConnThread) 611 return NS_ERROR_NOT_INITIALIZED; 612 613 ipcCallback *callback = new ipcCallback; 614 if (!callback) 615 return NS_ERROR_OUT_OF_MEMORY; 616 callback->func = func; 617 callback->arg = arg; 618 619 RTCritSectEnter(&gConnState->CritSect); 620 gConnState->callback_queue.Append(callback); 621 size_t cbWrittenIgn = 0; 622 int vrc = RTPipeWrite(gConnState->hWakeupPipeW, &magicChar, sizeof(magicChar), &cbWrittenIgn); 623 AssertRC(vrc); 624 RTCritSectLeave(&gConnState->CritSect); 625 return NS_OK; 626 } 627
Note:
See TracChangeset
for help on using the changeset viewer.