Changeset 101813 in vbox for trunk/src/libs/xpcom18a4/nsprpub
- Timestamp:
- Nov 5, 2023 11:26:07 AM (15 months ago)
- Location:
- trunk/src/libs/xpcom18a4/nsprpub/pr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/nsprpub/pr/include/private/primpl.h
r101811 r101813 456 456 struct pollfd *syspoll_list; /* Unix polling list used by PR_Poll */ 457 457 PRUint32 syspoll_count; /* number of elements in syspoll_list */ 458 #if defined(_PR_POLL_WITH_SELECT)459 int *selectfd_list; /* Unix fd's that PR_Poll selects on */460 PRUint32 selectfd_count; /* number of elements in selectfd_list */461 #endif462 458 }; 463 459 -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/pthreads/ptio.c
r101806 r101813 41 41 */ 42 42 43 #if defined(_PR_POLL_WITH_SELECT)44 #if !(defined(HPUX) && defined(_USE_BIG_FDS))45 /* set fd limit for select(), before including system header files */46 #define FD_SETSIZE (16 * 1024)47 #endif48 #endif49 50 43 #include <pthread.h> 51 44 #include <string.h> /* for memset() */ … … 293 286 */ 294 287 #define PT_DEFAULT_POLL_MSEC 5000 295 #if defined(_PR_POLL_WITH_SELECT)296 #define PT_DEFAULT_SELECT_SEC (PT_DEFAULT_POLL_MSEC/PR_MSEC_PER_SEC)297 #define PT_DEFAULT_SELECT_USEC \298 ((PT_DEFAULT_POLL_MSEC % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC)299 #endif300 288 301 289 /* … … 413 401 #endif /* DEBUG */ 414 402 415 #if defined(_PR_POLL_WITH_SELECT)416 /*417 * OSF1 and HPUX report the POLLHUP event for a socket when the418 * shutdown(SHUT_WR) operation is called for the remote end, even though419 * the socket is still writeable. Use select(), instead of poll(), to420 * workaround this problem.421 */422 static void pt_poll_now_with_select(pt_Continuation *op)423 {424 PRInt32 msecs;425 fd_set rd, wr, *rdp, *wrp;426 struct timeval tv;427 PRIntervalTime epoch, now, elapsed, remaining;428 PRBool wait_for_remaining;429 PRThread *self = PR_GetCurrentThread();430 431 PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);432 PR_ASSERT(op->arg1.osfd < FD_SETSIZE);433 434 switch (op->timeout) {435 case PR_INTERVAL_NO_TIMEOUT:436 tv.tv_sec = PT_DEFAULT_SELECT_SEC;437 tv.tv_usec = PT_DEFAULT_SELECT_USEC;438 do439 {440 PRIntn rv;441 442 if (op->event & POLLIN) {443 FD_ZERO(&rd);444 FD_SET(op->arg1.osfd, &rd);445 rdp = &rd;446 } else447 rdp = NULL;448 if (op->event & POLLOUT) {449 FD_ZERO(&wr);450 FD_SET(op->arg1.osfd, &wr);451 wrp = ≀452 } else453 wrp = NULL;454 455 rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);456 457 if (self->state & PT_THREAD_ABORTED)458 {459 self->state &= ~PT_THREAD_ABORTED;460 op->result.code = -1;461 op->syserrno = EINTR;462 op->status = pt_continuation_done;463 return;464 }465 466 if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN)))467 continue; /* go around the loop again */468 469 if (rv > 0)470 {471 PRInt16 revents = 0;472 473 if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd))474 revents |= POLLIN;475 if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr))476 revents |= POLLOUT;477 478 if (op->function(op, revents))479 op->status = pt_continuation_done;480 } else if (rv == -1) {481 op->result.code = -1;482 op->syserrno = errno;483 op->status = pt_continuation_done;484 }485 /* else, select timed out */486 } while (pt_continuation_done != op->status);487 break;488 default:489 now = epoch = PR_IntervalNow();490 remaining = op->timeout;491 do492 {493 PRIntn rv;494 495 if (op->event & POLLIN) {496 FD_ZERO(&rd);497 FD_SET(op->arg1.osfd, &rd);498 rdp = &rd;499 } else500 rdp = NULL;501 if (op->event & POLLOUT) {502 FD_ZERO(&wr);503 FD_SET(op->arg1.osfd, &wr);504 wrp = ≀505 } else506 wrp = NULL;507 508 wait_for_remaining = PR_TRUE;509 msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);510 if (msecs > PT_DEFAULT_POLL_MSEC) {511 wait_for_remaining = PR_FALSE;512 msecs = PT_DEFAULT_POLL_MSEC;513 }514 tv.tv_sec = msecs/PR_MSEC_PER_SEC;515 tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC;516 rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);517 518 if (self->state & PT_THREAD_ABORTED)519 {520 self->state &= ~PT_THREAD_ABORTED;521 op->result.code = -1;522 op->syserrno = EINTR;523 op->status = pt_continuation_done;524 return;525 }526 527 if (rv > 0) {528 PRInt16 revents = 0;529 530 if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd))531 revents |= POLLIN;532 if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr))533 revents |= POLLOUT;534 535 if (op->function(op, revents))536 op->status = pt_continuation_done;537 538 } else if ((rv == 0) ||539 ((errno == EINTR) || (errno == EAGAIN))) {540 if (rv == 0) { /* select timed out */541 if (wait_for_remaining)542 now += remaining;543 else544 now += PR_MillisecondsToInterval(msecs);545 } else546 now = PR_IntervalNow();547 elapsed = (PRIntervalTime) (now - epoch);548 if (elapsed >= op->timeout) {549 op->result.code = -1;550 op->syserrno = ETIMEDOUT;551 op->status = pt_continuation_done;552 } else553 remaining = op->timeout - elapsed;554 } else {555 op->result.code = -1;556 op->syserrno = errno;557 op->status = pt_continuation_done;558 }559 } while (pt_continuation_done != op->status);560 break;561 }562 563 } /* pt_poll_now_with_select */564 565 #endif /* _PR_POLL_WITH_SELECT */566 567 403 static void pt_poll_now(pt_Continuation *op) 568 404 { … … 573 409 574 410 PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout); 575 #if defined (_PR_POLL_WITH_SELECT)576 /*577 * If the fd is small enough call the select-based poll operation578 */579 if (op->arg1.osfd < FD_SETSIZE) {580 pt_poll_now_with_select(op);581 return;582 }583 #endif584 411 585 412 switch (op->timeout) { … … 3330 3157 } /* _pr_poll_with_poll */ 3331 3158 3332 #if defined(_PR_POLL_WITH_SELECT)3333 /*3334 * OSF1 and HPUX report the POLLHUP event for a socket when the3335 * shutdown(SHUT_WR) operation is called for the remote end, even though3336 * the socket is still writeable. Use select(), instead of poll(), to3337 * workaround this problem.3338 */3339 static PRInt32 _pr_poll_with_select(3340 PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)3341 {3342 PRInt32 ready = 0;3343 /*3344 * For restarting select() if it is interrupted by a signal.3345 * We use these variables to figure out how much time has3346 * elapsed and how much of the timeout still remains.3347 */3348 PRIntervalTime start, elapsed, remaining;3349 3350 if (pt_TestAbort()) return -1;3351 3352 if (0 == npds) PR_Sleep(timeout);3353 else3354 {3355 #define STACK_POLL_DESC_COUNT 643356 int stack_selectfd[STACK_POLL_DESC_COUNT];3357 int *selectfd;3358 fd_set rd, wr, ex, *rdp = NULL, *wrp = NULL, *exp = NULL;3359 struct timeval tv, *tvp;3360 PRIntn index, msecs, maxfd = 0;3361 3362 if (npds <= STACK_POLL_DESC_COUNT)3363 {3364 selectfd = stack_selectfd;3365 }3366 else3367 {3368 PRThread *me = PR_GetCurrentThread();3369 if (npds > me->selectfd_count)3370 {3371 PR_Free(me->selectfd_list);3372 me->selectfd_list = (int *)PR_MALLOC(npds * sizeof(int));3373 if (NULL == me->selectfd_list)3374 {3375 me->selectfd_count = 0;3376 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);3377 return -1;3378 }3379 me->selectfd_count = npds;3380 }3381 selectfd = me->selectfd_list;3382 }3383 FD_ZERO(&rd);3384 FD_ZERO(&wr);3385 FD_ZERO(&ex);3386 3387 for (index = 0; index < npds; ++index)3388 {3389 PRInt16 in_flags_read = 0, in_flags_write = 0;3390 PRInt16 out_flags_read = 0, out_flags_write = 0;3391 3392 if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))3393 {3394 if (pds[index].in_flags & PR_POLL_READ)3395 {3396 in_flags_read = (pds[index].fd->methods->poll)(3397 pds[index].fd,3398 pds[index].in_flags & ~PR_POLL_WRITE,3399 &out_flags_read);3400 }3401 if (pds[index].in_flags & PR_POLL_WRITE)3402 {3403 in_flags_write = (pds[index].fd->methods->poll)(3404 pds[index].fd,3405 pds[index].in_flags & ~PR_POLL_READ,3406 &out_flags_write);3407 }3408 if ((0 != (in_flags_read & out_flags_read))3409 || (0 != (in_flags_write & out_flags_write)))3410 {3411 /* this one is ready right now */3412 if (0 == ready)3413 {3414 /*3415 * We will return without calling the system3416 * poll function. So zero the out_flags3417 * fields of all the poll descriptors before3418 * this one.3419 */3420 int i;3421 for (i = 0; i < index; i++)3422 {3423 pds[i].out_flags = 0;3424 }3425 }3426 ready += 1;3427 pds[index].out_flags = out_flags_read | out_flags_write;3428 }3429 else3430 {3431 /* now locate the NSPR layer at the bottom of the stack */3432 PRFileDesc *bottom = PR_GetIdentitiesLayer(3433 pds[index].fd, PR_NSPR_IO_LAYER);3434 PR_ASSERT(NULL != bottom); /* what to do about that? */3435 pds[index].out_flags = 0; /* pre-condition */3436 if ((NULL != bottom)3437 && (_PR_FILEDESC_OPEN == bottom->secret->state))3438 {3439 if (0 == ready)3440 {3441 PRBool add_to_rd = PR_FALSE;3442 PRBool add_to_wr = PR_FALSE;3443 PRBool add_to_ex = PR_FALSE;3444 3445 selectfd[index] = bottom->secret->md.osfd;3446 if (in_flags_read & PR_POLL_READ)3447 {3448 pds[index].out_flags |=3449 _PR_POLL_READ_SYS_READ;3450 add_to_rd = PR_TRUE;3451 }3452 if (in_flags_read & PR_POLL_WRITE)3453 {3454 pds[index].out_flags |=3455 _PR_POLL_READ_SYS_WRITE;3456 add_to_wr = PR_TRUE;3457 }3458 if (in_flags_write & PR_POLL_READ)3459 {3460 pds[index].out_flags |=3461 _PR_POLL_WRITE_SYS_READ;3462 add_to_rd = PR_TRUE;3463 }3464 if (in_flags_write & PR_POLL_WRITE)3465 {3466 pds[index].out_flags |=3467 _PR_POLL_WRITE_SYS_WRITE;3468 add_to_wr = PR_TRUE;3469 }3470 if (pds[index].in_flags & PR_POLL_EXCEPT)3471 {3472 add_to_ex = PR_TRUE;3473 }3474 if ((selectfd[index] > maxfd) &&3475 (add_to_rd || add_to_wr || add_to_ex))3476 {3477 maxfd = selectfd[index];3478 /*3479 * If maxfd is too large to be used with3480 * select, fall back to calling poll.3481 */3482 if (maxfd >= FD_SETSIZE)3483 break;3484 }3485 if (add_to_rd)3486 {3487 FD_SET(bottom->secret->md.osfd, &rd);3488 rdp = &rd;3489 }3490 if (add_to_wr)3491 {3492 FD_SET(bottom->secret->md.osfd, &wr);3493 wrp = ≀3494 }3495 if (add_to_ex)3496 {3497 FD_SET(bottom->secret->md.osfd, &ex);3498 exp = &ex;3499 }3500 }3501 }3502 else3503 {3504 if (0 == ready)3505 {3506 int i;3507 for (i = 0; i < index; i++)3508 {3509 pds[i].out_flags = 0;3510 }3511 }3512 ready += 1; /* this will cause an abrupt return */3513 pds[index].out_flags = PR_POLL_NVAL; /* bogii */3514 }3515 }3516 }3517 else3518 {3519 pds[index].out_flags = 0;3520 }3521 }3522 if (0 == ready)3523 {3524 if (maxfd >= FD_SETSIZE)3525 {3526 /*3527 * maxfd too large to be used with select, fall back to3528 * calling poll3529 */3530 return(_pr_poll_with_poll(pds, npds, timeout));3531 }3532 switch (timeout)3533 {3534 case PR_INTERVAL_NO_WAIT:3535 tv.tv_sec = 0;3536 tv.tv_usec = 0;3537 tvp = &tv;3538 break;3539 case PR_INTERVAL_NO_TIMEOUT:3540 tvp = NULL;3541 break;3542 default:3543 msecs = PR_IntervalToMilliseconds(timeout);3544 tv.tv_sec = msecs/PR_MSEC_PER_SEC;3545 tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC;3546 tvp = &tv;3547 start = PR_IntervalNow();3548 }3549 3550 retry:3551 ready = select(maxfd + 1, rdp, wrp, exp, tvp);3552 if (-1 == ready)3553 {3554 PRIntn oserror = errno;3555 3556 if ((EINTR == oserror) || (EAGAIN == oserror))3557 {3558 if (timeout == PR_INTERVAL_NO_TIMEOUT)3559 goto retry;3560 else if (timeout == PR_INTERVAL_NO_WAIT)3561 ready = 0; /* don't retry, just time out */3562 else3563 {3564 elapsed = (PRIntervalTime) (PR_IntervalNow()3565 - start);3566 if (elapsed > timeout)3567 ready = 0; /* timed out */3568 else3569 {3570 remaining = timeout - elapsed;3571 msecs = PR_IntervalToMilliseconds(remaining);3572 tv.tv_sec = msecs/PR_MSEC_PER_SEC;3573 tv.tv_usec = (msecs % PR_MSEC_PER_SEC) *3574 PR_USEC_PER_MSEC;3575 goto retry;3576 }3577 }3578 } else if (EBADF == oserror)3579 {3580 /* find all the bad fds */3581 ready = 0;3582 for (index = 0; index < npds; ++index)3583 {3584 pds[index].out_flags = 0;3585 if ((NULL != pds[index].fd) &&3586 (0 != pds[index].in_flags))3587 {3588 if (fcntl(selectfd[index], F_GETFL, 0) == -1)3589 {3590 pds[index].out_flags = PR_POLL_NVAL;3591 ready++;3592 }3593 }3594 }3595 } else3596 _PR_MD_MAP_SELECT_ERROR(oserror);3597 }3598 else if (ready > 0)3599 {3600 for (index = 0; index < npds; ++index)3601 {3602 PRInt16 out_flags = 0;3603 if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))3604 {3605 if (FD_ISSET(selectfd[index], &rd))3606 {3607 if (pds[index].out_flags3608 & _PR_POLL_READ_SYS_READ)3609 {3610 out_flags |= PR_POLL_READ;3611 }3612 if (pds[index].out_flags3613 & _PR_POLL_WRITE_SYS_READ)3614 {3615 out_flags |= PR_POLL_WRITE;3616 }3617 }3618 if (FD_ISSET(selectfd[index], &wr))3619 {3620 if (pds[index].out_flags3621 & _PR_POLL_READ_SYS_WRITE)3622 {3623 out_flags |= PR_POLL_READ;3624 }3625 if (pds[index].out_flags3626 & _PR_POLL_WRITE_SYS_WRITE)3627 {3628 out_flags |= PR_POLL_WRITE;3629 }3630 }3631 if (FD_ISSET(selectfd[index], &ex))3632 out_flags |= PR_POLL_EXCEPT;3633 }3634 pds[index].out_flags = out_flags;3635 }3636 }3637 }3638 }3639 return ready;3640 3641 } /* _pr_poll_with_select */3642 #endif /* _PR_POLL_WITH_SELECT */3643 3644 3159 PR_IMPLEMENT(PRInt32) PR_Poll( 3645 3160 PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) 3646 3161 { 3647 #if defined(_PR_POLL_WITH_SELECT)3648 return(_pr_poll_with_select(pds, npds, timeout));3649 #else3650 3162 return(_pr_poll_with_poll(pds, npds, timeout)); 3651 #endif3652 3163 } 3653 3164 -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/pthreads/ptthread.c
r101805 r101813 843 843 if (NULL != thred->syspoll_list) 844 844 PR_Free(thred->syspoll_list); 845 #if defined(_PR_POLL_WITH_SELECT)846 if (NULL != thred->selectfd_list)847 PR_Free(thred->selectfd_list);848 #endif849 845 #if defined(DEBUG) 850 846 memset(thred, 0xaf, sizeof(PRThread));
Note:
See TracChangeset
for help on using the changeset viewer.