зеркало из https://github.com/mozilla/pjs.git
Bugzilla bug 100776: handle non-blocking connect correctly on OS/2.
The fix is contributed by Javier Pedemonte <pedemont@us.ibm.com>. r=mkaply. Modified files: configure configure.in _os2.h _os2_errors.h prsocket.c os2_errors.c os2poll.c os2sock.c
This commit is contained in:
Родитель
880fdbee62
Коммит
72a56c320d
|
@ -4538,10 +4538,6 @@ EOF
|
|||
*-os2*)
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define XP_OS2 1
|
||||
EOF
|
||||
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define BSD_SELECT 1
|
||||
EOF
|
||||
|
||||
cat >> confdefs.h <<\EOF
|
||||
|
@ -4568,6 +4564,10 @@ EOF
|
|||
if test "$GNU_CC"; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define XP_OS2_EMX 1
|
||||
EOF
|
||||
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define BSD_SELECT 1
|
||||
EOF
|
||||
|
||||
cat >> confdefs.h <<\EOF
|
||||
|
@ -5573,7 +5573,7 @@ s%\[%\\&%g
|
|||
s%\]%\\&%g
|
||||
s%\$%$$%g
|
||||
EOF
|
||||
DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' ' | tr '\015' ' '`
|
||||
DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' ' | tr '\015' ' '`
|
||||
rm -f conftest.defs
|
||||
|
||||
|
||||
|
|
|
@ -1674,7 +1674,6 @@ mips-sony-newsos*)
|
|||
|
||||
*-os2*)
|
||||
AC_DEFINE(XP_OS2)
|
||||
AC_DEFINE(BSD_SELECT)
|
||||
AC_DEFINE(XP_PC)
|
||||
AC_DEFINE(_PR_GLOBAL_THREADS_ONLY)
|
||||
OBJ_SUFFIX=obj
|
||||
|
@ -1692,6 +1691,7 @@ mips-sony-newsos*)
|
|||
# EMX/GCC build
|
||||
if test "$GNU_CC"; then
|
||||
AC_DEFINE(XP_OS2_EMX)
|
||||
AC_DEFINE(BSD_SELECT)
|
||||
AC_DEFINE(OS2)
|
||||
AR=emxomfar
|
||||
AR_FLAGS='-p256 r $@'
|
||||
|
|
|
@ -537,4 +537,6 @@ unsigned long _System _DLL_InitTerm( unsigned long mod_handle, unsigned long fla
|
|||
#define FreeLibrary(x) DosFreeModule((HMODULE)x)
|
||||
#define OutputDebugString(x)
|
||||
|
||||
extern int _MD_os2_get_nonblocking_connect_error(int osfd);
|
||||
|
||||
#endif /* nspr_os2_defs_h___ */
|
||||
|
|
|
@ -46,8 +46,8 @@ NSPR_API(void) _MD_os2_map_opendir_error(PRInt32 err);
|
|||
NSPR_API(void) _MD_os2_map_closedir_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_CLOSEDIR_ERROR _MD_os2_map_closedir_error
|
||||
|
||||
NSPR_API(void) _MD_unix_readdir_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_READDIR_ERROR _MD_unix_readdir_error
|
||||
NSPR_API(void) _MD_os2_readdir_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_READDIR_ERROR _MD_os2_readdir_error
|
||||
|
||||
NSPR_API(void) _MD_os2_map_delete_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_DELETE_ERROR _MD_os2_map_delete_error
|
||||
|
@ -103,6 +103,9 @@ NSPR_API(void) _MD_os2_map_send_error(PRInt32 err);
|
|||
NSPR_API(void) _MD_os2_map_sendto_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_SENDTO_ERROR _MD_os2_map_sendto_error
|
||||
|
||||
NSPR_API(void) _MD_os2_map_writev_error(int err);
|
||||
#define _PR_MD_MAP_WRITEV_ERROR _MD_os2_map_writev_error
|
||||
|
||||
NSPR_API(void) _MD_os2_map_accept_error(PRInt32 err);
|
||||
#define _PR_MD_MAP_ACCEPT_ERROR _MD_os2_map_accept_error
|
||||
|
||||
|
|
|
@ -338,22 +338,11 @@ static PRStatus PR_CALLBACK SocketConnectContinue(
|
|||
|
||||
#elif defined(XP_OS2)
|
||||
|
||||
if (out_flags & PR_POLL_EXCEPT) {
|
||||
int len = sizeof(err);
|
||||
if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len)
|
||||
< 0) {
|
||||
_PR_MD_MAP_GETSOCKOPT_ERROR(sock_errno());
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (err != 0) {
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
} else {
|
||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||
}
|
||||
err = _MD_os2_get_nonblocking_connect_error(osfd);
|
||||
if (err != 0) {
|
||||
_PR_MD_MAP_CONNECT_ERROR(err);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
PR_ASSERT(out_flags & PR_POLL_WRITE);
|
||||
return PR_SUCCESS;
|
||||
|
||||
#elif defined(XP_MAC)
|
||||
|
|
|
@ -35,6 +35,44 @@
|
|||
#include "prerror.h"
|
||||
#include "primpl.h"
|
||||
|
||||
void _MD_os2_map_default_error(PRInt32 err)
|
||||
{
|
||||
switch (err) {
|
||||
case EWOULDBLOCK:
|
||||
PR_SetError(PR_WOULD_BLOCK_ERROR, err);
|
||||
break;
|
||||
case EBADF:
|
||||
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
|
||||
break;
|
||||
case ENOTSOCK:
|
||||
PR_SetError(PR_NOT_SOCKET_ERROR, err);
|
||||
break;
|
||||
case EMSGSIZE:
|
||||
case EINVAL:
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
|
||||
break;
|
||||
case ENOBUFS:
|
||||
PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
|
||||
break;
|
||||
case ECONNREFUSED:
|
||||
PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
|
||||
break;
|
||||
case EISCONN:
|
||||
PR_SetError(PR_IS_CONNECTED_ERROR, err);
|
||||
break;
|
||||
#ifdef SOCEFAULT
|
||||
case SOCEFAULT:
|
||||
PR_SetError(PR_ACCESS_FAULT_ERROR, err);
|
||||
break;
|
||||
#endif
|
||||
case ERROR_NETNAME_DELETED:
|
||||
PR_SetError(PR_CONNECT_RESET_ERROR, err);
|
||||
break;
|
||||
default:
|
||||
PR_SetError(PR_UNKNOWN_ERROR, err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void _MD_os2_map_opendir_error(PRInt32 err)
|
||||
{
|
||||
switch (err) {
|
||||
|
@ -92,7 +130,7 @@ void _MD_os2_map_closedir_error(PRInt32 err)
|
|||
}
|
||||
}
|
||||
|
||||
void _MD_unix_readdir_error(PRInt32 err)
|
||||
void _MD_os2_readdir_error(PRInt32 err)
|
||||
{
|
||||
|
||||
switch (err) {
|
||||
|
@ -671,73 +709,17 @@ void _MD_os2_map_send_error(PRInt32 err)
|
|||
|
||||
void _MD_os2_map_sendto_error(PRInt32 err)
|
||||
{
|
||||
switch (err) {
|
||||
case EWOULDBLOCK:
|
||||
PR_SetError(PR_WOULD_BLOCK_ERROR, err);
|
||||
break;
|
||||
case EBADF:
|
||||
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
|
||||
break;
|
||||
case ENOTSOCK:
|
||||
PR_SetError(PR_NOT_SOCKET_ERROR, err);
|
||||
break;
|
||||
case EMSGSIZE:
|
||||
case EINVAL:
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
|
||||
break;
|
||||
case ENOBUFS:
|
||||
PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
|
||||
break;
|
||||
case ECONNREFUSED:
|
||||
PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
|
||||
break;
|
||||
case EISCONN:
|
||||
PR_SetError(PR_IS_CONNECTED_ERROR, err);
|
||||
break;
|
||||
#ifdef SOCEFAULT
|
||||
case SOCEFAULT:
|
||||
PR_SetError(PR_ACCESS_FAULT_ERROR, err);
|
||||
break;
|
||||
#endif
|
||||
case ERROR_NETNAME_DELETED:
|
||||
PR_SetError(PR_CONNECT_RESET_ERROR, err);
|
||||
break;
|
||||
default:
|
||||
PR_SetError(PR_UNKNOWN_ERROR, err);
|
||||
break;
|
||||
}
|
||||
_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void _MD_os2_map_writev_error(int err)
|
||||
{
|
||||
_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void _MD_os2_map_accept_error(PRInt32 err)
|
||||
{
|
||||
switch (err) {
|
||||
case EWOULDBLOCK:
|
||||
PR_SetError(PR_WOULD_BLOCK_ERROR, err);
|
||||
break;
|
||||
case EBADF:
|
||||
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
|
||||
break;
|
||||
case ENOTSOCK:
|
||||
PR_SetError(PR_NOT_SOCKET_ERROR, err);
|
||||
break;
|
||||
case EOPNOTSUPP:
|
||||
PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
|
||||
break;
|
||||
#ifdef SOCEFAULT
|
||||
case SOCEFAULT:
|
||||
PR_SetError(PR_ACCESS_FAULT_ERROR, err);
|
||||
break;
|
||||
#endif
|
||||
case EMFILE:
|
||||
PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
|
||||
break;
|
||||
case ENOBUFS:
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
|
||||
break;
|
||||
default:
|
||||
PR_SetError(PR_UNKNOWN_ERROR, err);
|
||||
break;
|
||||
}
|
||||
_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void _MD_os2_map_acceptex_error(PRInt32 err)
|
||||
|
@ -759,6 +741,21 @@ void _MD_os2_map_acceptex_error(PRInt32 err)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An error code of 0 means that the nonblocking connect succeeded.
|
||||
*/
|
||||
|
||||
int _MD_os2_get_nonblocking_connect_error(int osfd)
|
||||
{
|
||||
int err;
|
||||
int len = sizeof(err);
|
||||
if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == -1) {
|
||||
return sock_errno();
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
void _MD_os2_map_connect_error(PRInt32 err)
|
||||
{
|
||||
switch (err) {
|
||||
|
|
|
@ -37,54 +37,64 @@
|
|||
*/
|
||||
|
||||
#ifdef XP_OS2_EMX
|
||||
#include <sys/time.h> /* For timeval. */
|
||||
#include <sys/time.h> /* For timeval. */
|
||||
#endif
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
PRInt32 _PR_MD_PR_POLL(
|
||||
PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
||||
#ifndef BSD_SELECT
|
||||
/* Utility functions called when using OS/2 select */
|
||||
|
||||
PRBool IsSocketSet( PRInt32 osfd, int* socks, int start, int count )
|
||||
{
|
||||
PRInt32 osfd;
|
||||
int maxfd = -1;
|
||||
int i;
|
||||
PRBool isSet = PR_FALSE;
|
||||
|
||||
for( i = start; i < start+count; i++ )
|
||||
{
|
||||
if( socks[i] == osfd )
|
||||
isSet = PR_TRUE;
|
||||
}
|
||||
|
||||
return isSet;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
|
||||
{
|
||||
#ifdef BSD_SELECT
|
||||
fd_set rd, wt, ex;
|
||||
#else
|
||||
int rd, wt, ex;
|
||||
int* socks;
|
||||
unsigned long msecs;
|
||||
int i, j;
|
||||
#endif
|
||||
PRFileDesc *bottom;
|
||||
PRPollDesc *pd, *epd;
|
||||
PRInt32 ready, err;
|
||||
PRThread *me = _PR_MD_CURRENT_THREAD();
|
||||
PRInt32 maxfd = -1, ready, err;
|
||||
PRIntervalTime remaining, elapsed, start;
|
||||
|
||||
#ifdef BSD_SELECT
|
||||
struct timeval tv, *tvp = NULL;
|
||||
|
||||
/*
|
||||
* For restarting _MD_SELECT() if it is interrupted by a signal.
|
||||
* We use these variables to figure out how much time has elapsed
|
||||
* and how much of the timeout still remains.
|
||||
*/
|
||||
PRIntervalTime start, elapsed, remaining;
|
||||
|
||||
if (_PR_PENDING_INTERRUPT(me))
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wt);
|
||||
FD_ZERO(&ex);
|
||||
#else
|
||||
rd = 0;
|
||||
wt = 0;
|
||||
ex = 0;
|
||||
socks = (int) PR_MALLOC( npds * 3 * sizeof(int) );
|
||||
|
||||
if (!socks)
|
||||
{
|
||||
me->flags &= ~_PR_INTERRUPT;
|
||||
PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Is it an empty set? If so, just sleep for the timeout and return
|
||||
*/
|
||||
if (0 == npds)
|
||||
{
|
||||
PR_Sleep(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
remaining = timeout;
|
||||
start = PR_IntervalNow();
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wt);
|
||||
FD_ZERO(&ex);
|
||||
|
||||
ready = 0;
|
||||
ready = 0;
|
||||
for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
||||
{
|
||||
PRInt16 in_flags_read = 0, in_flags_write = 0;
|
||||
|
@ -95,19 +105,17 @@ PRInt32 _PR_MD_PR_POLL(
|
|||
if (pd->in_flags & PR_POLL_READ)
|
||||
{
|
||||
in_flags_read = (pd->fd->methods->poll)(
|
||||
pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_WRITE),
|
||||
&out_flags_read);
|
||||
pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
|
||||
}
|
||||
if (pd->in_flags & PR_POLL_WRITE)
|
||||
{
|
||||
in_flags_write = (pd->fd->methods->poll)(
|
||||
pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_READ),
|
||||
&out_flags_write);
|
||||
pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
|
||||
}
|
||||
if ((0 != (in_flags_read & out_flags_read))
|
||||
|| (0 != (in_flags_write & out_flags_write)))
|
||||
if ((0 != (in_flags_read & out_flags_read)) ||
|
||||
(0 != (in_flags_write & out_flags_write)))
|
||||
{
|
||||
/* this one's ready right now (buffered input) */
|
||||
/* this one's ready right now */
|
||||
if (0 == ready)
|
||||
{
|
||||
/*
|
||||
|
@ -128,37 +136,67 @@ PRInt32 _PR_MD_PR_POLL(
|
|||
else
|
||||
{
|
||||
pd->out_flags = 0; /* pre-condition */
|
||||
|
||||
/* make sure this is an NSPR supported stack */
|
||||
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
PR_ASSERT(NULL != bottom); /* what to do about that? */
|
||||
if ((NULL != bottom)
|
||||
&& (_PR_FILEDESC_OPEN == bottom->secret->state))
|
||||
if ((NULL != bottom) &&
|
||||
(_PR_FILEDESC_OPEN == bottom->secret->state))
|
||||
{
|
||||
if (0 == ready)
|
||||
{
|
||||
osfd = bottom->secret->md.osfd;
|
||||
if (osfd > maxfd) maxfd = osfd;
|
||||
PRInt32 osfd = bottom->secret->md.osfd;
|
||||
if (osfd > maxfd)
|
||||
maxfd = osfd;
|
||||
if (in_flags_read & PR_POLL_READ)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_READ_SYS_READ;
|
||||
#ifdef BSD_SELECT
|
||||
FD_SET(osfd, &rd);
|
||||
#else
|
||||
socks[rd] = osfd;
|
||||
rd++;
|
||||
#endif
|
||||
}
|
||||
if (in_flags_read & PR_POLL_WRITE)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
|
||||
#ifdef BSD_SELECT
|
||||
FD_SET(osfd, &wt);
|
||||
#else
|
||||
socks[npds+wt] = osfd;
|
||||
wt++;
|
||||
#endif
|
||||
}
|
||||
if (in_flags_write & PR_POLL_READ)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
|
||||
#ifdef BSD_SELECT
|
||||
FD_SET(osfd, &rd);
|
||||
#else
|
||||
socks[rd] = osfd;
|
||||
rd++;
|
||||
#endif
|
||||
}
|
||||
if (in_flags_write & PR_POLL_WRITE)
|
||||
{
|
||||
pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
|
||||
#ifdef BSD_SELECT
|
||||
FD_SET(osfd, &wt);
|
||||
#else
|
||||
socks[npds+wt] = osfd;
|
||||
wt++;
|
||||
#endif
|
||||
}
|
||||
if (pd->in_flags & PR_POLL_EXCEPT)
|
||||
{
|
||||
#ifdef BSD_SELECT
|
||||
FD_SET(osfd, &ex);
|
||||
#else
|
||||
socks[npds*2+ex] = osfd;
|
||||
ex++;
|
||||
#endif
|
||||
}
|
||||
if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -178,9 +216,19 @@ PRInt32 _PR_MD_PR_POLL(
|
|||
}
|
||||
}
|
||||
|
||||
if (0 != ready) return ready; /* no need to block */
|
||||
if (0 != ready)
|
||||
{
|
||||
#ifndef BSD_SELECT
|
||||
free(socks);
|
||||
#endif
|
||||
return ready; /* no need to block */
|
||||
}
|
||||
|
||||
remaining = timeout;
|
||||
start = PR_IntervalNow();
|
||||
|
||||
retry:
|
||||
#ifdef BSD_SELECT
|
||||
if (timeout != PR_INTERVAL_NO_TIMEOUT)
|
||||
{
|
||||
PRInt32 ticksPerSecond = PR_TicksPerSecond();
|
||||
|
@ -191,21 +239,50 @@ retry:
|
|||
}
|
||||
|
||||
ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
|
||||
if (ready == -1 && errno == EINTR)
|
||||
#else
|
||||
switch (timeout)
|
||||
{
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
|
||||
else
|
||||
{
|
||||
elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
|
||||
if (elapsed > timeout) ready = 0; /* timed out */
|
||||
else
|
||||
{
|
||||
remaining = timeout - elapsed;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
case PR_INTERVAL_NO_WAIT:
|
||||
msecs = 0;
|
||||
break;
|
||||
case PR_INTERVAL_NO_TIMEOUT:
|
||||
msecs = -1;
|
||||
break;
|
||||
default:
|
||||
msecs = PR_IntervalToMilliseconds(remaining);
|
||||
}
|
||||
|
||||
/* compact array */
|
||||
for( i = rd, j = npds; j < npds+wt; i++,j++ )
|
||||
socks[i] = socks[j];
|
||||
for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ )
|
||||
socks[i] = socks[j];
|
||||
|
||||
ready = _MD_SELECT(socks, rd, wt, ex, msecs);
|
||||
#endif
|
||||
|
||||
if (ready == -1 && errno == SOCEINTR)
|
||||
{
|
||||
if (timeout == PR_INTERVAL_NO_TIMEOUT)
|
||||
goto retry;
|
||||
else
|
||||
{
|
||||
elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
|
||||
if (elapsed > timeout)
|
||||
ready = 0; /* timed out */
|
||||
else
|
||||
{
|
||||
remaining = timeout - elapsed;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Now to unravel the select sets back into the client's poll
|
||||
** descriptor list. Is this possibly an area for pissing away
|
||||
** a few cycles or what?
|
||||
*/
|
||||
if (ready > 0)
|
||||
{
|
||||
ready = 0;
|
||||
|
@ -214,26 +291,44 @@ retry:
|
|||
PRInt16 out_flags = 0;
|
||||
if ((NULL != pd->fd) && (0 != pd->in_flags))
|
||||
{
|
||||
PRInt32 osfd;
|
||||
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
PR_ASSERT(NULL != bottom);
|
||||
|
||||
osfd = bottom->secret->md.osfd;
|
||||
|
||||
#ifdef BSD_SELECT
|
||||
if (FD_ISSET(osfd, &rd))
|
||||
#else
|
||||
if( IsSocketSet(osfd, socks, 0, rd) )
|
||||
#endif
|
||||
{
|
||||
if (pd->out_flags & _PR_POLL_READ_SYS_READ)
|
||||
out_flags |= PR_POLL_READ;
|
||||
if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
|
||||
out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSD_SELECT
|
||||
if (FD_ISSET(osfd, &wt))
|
||||
#else
|
||||
if( IsSocketSet(osfd, socks, rd, wt) )
|
||||
#endif
|
||||
{
|
||||
if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
|
||||
out_flags |= PR_POLL_READ;
|
||||
if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
|
||||
out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
|
||||
#ifdef BSD_SELECT
|
||||
if (FD_ISSET(osfd, &ex))
|
||||
#else
|
||||
if( IsSocketSet(osfd, socks, rd+wt, ex) )
|
||||
#endif
|
||||
{
|
||||
out_flags |= PR_POLL_EXCEPT;
|
||||
}
|
||||
if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
|
||||
}
|
||||
pd->out_flags = out_flags;
|
||||
if (out_flags) ready++;
|
||||
|
@ -242,39 +337,42 @@ retry:
|
|||
}
|
||||
else if (ready < 0)
|
||||
{
|
||||
err = _MD_ERRNO();
|
||||
if (err == EBADF)
|
||||
err = _MD_ERRNO();
|
||||
if (err == EBADF)
|
||||
{
|
||||
/* Find the bad fds */
|
||||
ready = 0;
|
||||
for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
||||
/* Find the bad fds */
|
||||
int optval;
|
||||
int optlen = sizeof(optval);
|
||||
ready = 0;
|
||||
for (pd = pds, epd = pd + npds; pd < epd; pd++)
|
||||
{
|
||||
int optval;
|
||||
int optlen = sizeof(optval);
|
||||
pd->out_flags = 0;
|
||||
if ((NULL == pd->fd) || (pd->in_flags == 0)) continue;
|
||||
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
|
||||
SO_TYPE, (char *) &optval, &optlen) == -1)
|
||||
pd->out_flags = 0;
|
||||
if ((NULL != pd->fd) && (0 != pd->in_flags))
|
||||
{
|
||||
PR_ASSERT(_MD_ERRNO() == ENOTSOCK);
|
||||
if (_MD_ERRNO() == ENOTSOCK)
|
||||
bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
|
||||
SO_TYPE, (char *) &optval, &optlen) == -1)
|
||||
{
|
||||
pd->out_flags = PR_POLL_NVAL;
|
||||
ready++;
|
||||
PR_ASSERT(sock_errno() == SOCENOTSOCK);
|
||||
if (sock_errno() == SOCENOTSOCK)
|
||||
{
|
||||
pd->out_flags = PR_POLL_NVAL;
|
||||
ready++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PR_ASSERT(ready > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_ASSERT(err != EINTR); /* should have been handled above */
|
||||
_PR_MD_MAP_SELECT_ERROR(err);
|
||||
}
|
||||
PR_ASSERT(ready > 0);
|
||||
}
|
||||
}
|
||||
return ready;
|
||||
}
|
||||
else
|
||||
_PR_MD_MAP_SELECT_ERROR(err);
|
||||
}
|
||||
|
||||
#ifndef BSD_SELECT
|
||||
free(socks);
|
||||
#endif
|
||||
return ready;
|
||||
}
|
||||
|
||||
#ifdef XP_OS2_EMX
|
||||
HMTX thread_select_mutex = 0; /* because EMX's select is not thread safe - duh! */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче