зеркало из https://github.com/mozilla/gecko-dev.git
For the IO continuation operation, use select(), instead of poll(),
on OSF1. Bug #153459.
This commit is contained in:
Родитель
9fdbed74a4
Коммит
d254f1ca9a
|
@ -23,6 +23,11 @@
|
||||||
|
|
||||||
#if defined(_PR_PTHREADS)
|
#if defined(_PR_PTHREADS)
|
||||||
|
|
||||||
|
#if defined(OSF1)
|
||||||
|
/* set fd limit for select(), before including system header files */
|
||||||
|
#define FD_SETSIZE (16 * 1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <string.h> /* for memset() */
|
#include <string.h> /* for memset() */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -190,6 +195,11 @@ static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
|
||||||
* might hang up before an interrupt is noticed.
|
* might hang up before an interrupt is noticed.
|
||||||
*/
|
*/
|
||||||
#define PT_DEFAULT_POLL_MSEC 5000
|
#define PT_DEFAULT_POLL_MSEC 5000
|
||||||
|
#if defined(OSF1)
|
||||||
|
#define PT_DEFAULT_SELECT_SEC (PT_DEFAULT_POLL_MSEC/PR_MSEC_PER_SEC)
|
||||||
|
#define PT_DEFAULT_SELECT_USEC \
|
||||||
|
((PT_DEFAULT_POLL_MSEC % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pt_SockLen is the type for the length of a socket address
|
* pt_SockLen is the type for the length of a socket address
|
||||||
|
@ -304,6 +314,150 @@ PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
|
||||||
|
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
#if defined(OSF1)
|
||||||
|
/*
|
||||||
|
* OSF1 reports the POLLHUP event for a socket when the shutdown(SHUT_WR)
|
||||||
|
* operation is called for the remote end, even though the socket is still
|
||||||
|
* writeable. Use select(), instead of poll(), to workaround this problem.
|
||||||
|
*/
|
||||||
|
static void osf_pt_poll_now(pt_Continuation *op)
|
||||||
|
{
|
||||||
|
PRInt32 msecs;
|
||||||
|
fd_set rd, wr, *rdp, *wrp;
|
||||||
|
struct timeval tv;
|
||||||
|
PRIntervalTime epoch, now, elapsed, remaining;
|
||||||
|
PRThread *self = PR_GetCurrentThread();
|
||||||
|
|
||||||
|
PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
|
||||||
|
PR_ASSERT(op->arg1.osfd < FD_SETSIZE);
|
||||||
|
|
||||||
|
switch (op->timeout) {
|
||||||
|
case PR_INTERVAL_NO_TIMEOUT:
|
||||||
|
tv.tv_sec = PT_DEFAULT_SELECT_SEC;
|
||||||
|
tv.tv_usec = PT_DEFAULT_SELECT_USEC;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
PRIntn rv;
|
||||||
|
|
||||||
|
if (op->event & POLLIN) {
|
||||||
|
FD_ZERO(&rd);
|
||||||
|
FD_SET(op->arg1.osfd, &rd);
|
||||||
|
rdp = &rd;
|
||||||
|
} else
|
||||||
|
rdp = NULL;
|
||||||
|
if (op->event & POLLOUT) {
|
||||||
|
FD_ZERO(&wr);
|
||||||
|
FD_SET(op->arg1.osfd, &wr);
|
||||||
|
wrp = ≀
|
||||||
|
} else
|
||||||
|
wrp = NULL;
|
||||||
|
|
||||||
|
rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);
|
||||||
|
|
||||||
|
if (self->state & PT_THREAD_ABORTED)
|
||||||
|
{
|
||||||
|
self->state &= ~PT_THREAD_ABORTED;
|
||||||
|
op->result.code = -1;
|
||||||
|
op->syserrno = EINTR;
|
||||||
|
op->status = pt_continuation_done;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN)))
|
||||||
|
continue; /* go around the loop again */
|
||||||
|
|
||||||
|
if (rv > 0)
|
||||||
|
{
|
||||||
|
PRInt16 revents = 0;
|
||||||
|
|
||||||
|
if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd))
|
||||||
|
revents |= POLLIN;
|
||||||
|
if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr))
|
||||||
|
revents |= POLLOUT;
|
||||||
|
|
||||||
|
if (op->function(op, revents))
|
||||||
|
op->status = pt_continuation_done;
|
||||||
|
} else if (rv == -1) {
|
||||||
|
op->result.code = -1;
|
||||||
|
op->syserrno = errno;
|
||||||
|
op->status = pt_continuation_done;
|
||||||
|
}
|
||||||
|
/* else, select timed out */
|
||||||
|
} while (pt_continuation_done != op->status);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
now = epoch = PR_IntervalNow();
|
||||||
|
remaining = op->timeout;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
PRIntn rv;
|
||||||
|
|
||||||
|
if (op->event & POLLIN) {
|
||||||
|
FD_ZERO(&rd);
|
||||||
|
FD_SET(op->arg1.osfd, &rd);
|
||||||
|
rdp = &rd;
|
||||||
|
} else
|
||||||
|
rdp = NULL;
|
||||||
|
if (op->event & POLLOUT) {
|
||||||
|
FD_ZERO(&wr);
|
||||||
|
FD_SET(op->arg1.osfd, &wr);
|
||||||
|
wrp = ≀
|
||||||
|
} else
|
||||||
|
wrp = NULL;
|
||||||
|
|
||||||
|
msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);
|
||||||
|
if (msecs > PT_DEFAULT_POLL_MSEC)
|
||||||
|
msecs = PT_DEFAULT_POLL_MSEC;
|
||||||
|
tv.tv_sec = msecs/PR_MSEC_PER_SEC;
|
||||||
|
tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC;
|
||||||
|
rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);
|
||||||
|
|
||||||
|
if (self->state & PT_THREAD_ABORTED)
|
||||||
|
{
|
||||||
|
self->state &= ~PT_THREAD_ABORTED;
|
||||||
|
op->result.code = -1;
|
||||||
|
op->syserrno = EINTR;
|
||||||
|
op->status = pt_continuation_done;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rv > 0) {
|
||||||
|
PRInt16 revents = 0;
|
||||||
|
|
||||||
|
if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd))
|
||||||
|
revents |= POLLIN;
|
||||||
|
if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr))
|
||||||
|
revents |= POLLOUT;
|
||||||
|
|
||||||
|
if (op->function(op, revents))
|
||||||
|
op->status = pt_continuation_done;
|
||||||
|
|
||||||
|
} else if ((rv == 0) ||
|
||||||
|
((errno == EINTR) || (errno == EAGAIN))) {
|
||||||
|
if (rv == 0) /* select timed out */
|
||||||
|
now += PR_MillisecondsToInterval(msecs);
|
||||||
|
else
|
||||||
|
now = PR_IntervalNow();
|
||||||
|
elapsed = (PRIntervalTime) (now - epoch);
|
||||||
|
if (elapsed >= op->timeout) {
|
||||||
|
op->result.code = -1;
|
||||||
|
op->syserrno = ETIMEDOUT;
|
||||||
|
op->status = pt_continuation_done;
|
||||||
|
} else
|
||||||
|
remaining = op->timeout - elapsed;
|
||||||
|
} else {
|
||||||
|
op->result.code = -1;
|
||||||
|
op->syserrno = errno;
|
||||||
|
op->status = pt_continuation_done;
|
||||||
|
}
|
||||||
|
} while (pt_continuation_done != op->status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* osf_pt_poll_now */
|
||||||
|
|
||||||
|
#endif /* OSF1 */
|
||||||
|
|
||||||
static void pt_poll_now(pt_Continuation *op)
|
static void pt_poll_now(pt_Continuation *op)
|
||||||
{
|
{
|
||||||
PRInt32 msecs;
|
PRInt32 msecs;
|
||||||
|
@ -311,6 +465,15 @@ static void pt_poll_now(pt_Continuation *op)
|
||||||
PRThread *self = PR_GetCurrentThread();
|
PRThread *self = PR_GetCurrentThread();
|
||||||
|
|
||||||
PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
|
PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
|
||||||
|
#if defined (OSF1)
|
||||||
|
/*
|
||||||
|
* If the fd is small enough call the select-based poll operation
|
||||||
|
*/
|
||||||
|
if (op->arg1.osfd < FD_SETSIZE) {
|
||||||
|
osf_pt_poll_now(op);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (op->timeout) {
|
switch (op->timeout) {
|
||||||
case PR_INTERVAL_NO_TIMEOUT:
|
case PR_INTERVAL_NO_TIMEOUT:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче