diff options
Diffstat (limited to 'nsprpub/pr/src/io')
-rw-r--r-- | nsprpub/pr/src/io/prio.c | 4 | ||||
-rw-r--r-- | nsprpub/pr/src/io/prlayer.c | 59 | ||||
-rw-r--r-- | nsprpub/pr/src/io/prmmap.c | 9 | ||||
-rw-r--r-- | nsprpub/pr/src/io/prscanf.c | 8 | ||||
-rw-r--r-- | nsprpub/pr/src/io/prsocket.c | 115 |
5 files changed, 155 insertions, 40 deletions
diff --git a/nsprpub/pr/src/io/prio.c b/nsprpub/pr/src/io/prio.c index 78cbdf564..bf9763a2c 100644 --- a/nsprpub/pr/src/io/prio.c +++ b/nsprpub/pr/src/io/prio.c @@ -119,6 +119,10 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc( fd->methods = methods; fd->secret->state = _PR_FILEDESC_OPEN; fd->secret->md.osfd = osfd; +#if defined(_WIN64) + fd->secret->alreadyConnected = PR_FALSE; + fd->secret->overlappedActive = PR_FALSE; +#endif _PR_MD_INIT_FILEDESC(fd); } else { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); diff --git a/nsprpub/pr/src/io/prlayer.c b/nsprpub/pr/src/io/prlayer.c index cadb7ca3c..00da0287a 100644 --- a/nsprpub/pr/src/io/prlayer.c +++ b/nsprpub/pr/src/io/prlayer.c @@ -47,7 +47,8 @@ static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd) rv = fd->lower->methods->close(fd->lower); _PR_DestroyIOLayer(fd); return rv; - } else if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) { + } + if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) { /* * lower layers of new style stack */ @@ -201,16 +202,16 @@ static PRFileDesc* PR_CALLBACK pl_TopAccept ( return NULL; } - if (newstyle_stack) { - newstack->lower = newfd; - newfd->higher = newstack; - return newstack; - } else { - /* this PR_PushIOLayer call cannot fail */ - rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); - PR_ASSERT(PR_SUCCESS == rv); - return newfd; /* that's it */ - } + if (newstyle_stack) + { + newstack->lower = newfd; + newfd->higher = newstack; + return newstack; + } + /* this PR_PushIOLayer call cannot fail */ + rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack); + PR_ASSERT(PR_SUCCESS == rv); + return newfd; /* that's it */ } static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr) @@ -326,12 +327,11 @@ static PRInt32 PR_CALLBACK pl_DefAcceptread ( (*nd)->higher = newstack; *nd = newstack; return nbytes; - } else { - /* this PR_PushIOLayer call cannot fail */ - rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack); - PR_ASSERT(PR_SUCCESS == rv); - return nbytes; } + /* this PR_PushIOLayer call cannot fail */ + rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack); + PR_ASSERT(PR_SUCCESS == rv); + return nbytes; } static PRInt32 PR_CALLBACK pl_DefTransmitfile ( @@ -494,10 +494,9 @@ static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack) { if (NULL == stack) return PR_FAILURE; - else { - PR_DELETE(stack); - return PR_SUCCESS; - } + + PR_DELETE(stack); + return PR_SUCCESS; } /* _PR_DestroyIOLayer */ PR_IMPLEMENT(PRStatus) PR_PushIOLayer( @@ -652,9 +651,11 @@ retry: if ((NULL != names) && (identity < length)) { /* what we did is still okay */ - memcpy( - names, identity_cache.name, - identity_cache.length * sizeof(char*)); + if (identity_cache.length != 0) { + memcpy( + names, identity_cache.name, + identity_cache.length * sizeof(char*)); + } old = identity_cache.name; identity_cache.name = names; identity_cache.length = length; @@ -702,8 +703,8 @@ PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd) if (PR_IO_LAYER_HEAD == fd->identity) { PR_ASSERT(NULL != fd->lower); return fd->lower->identity; - } else - return fd->identity; + } + return fd->identity; } /* PR_GetLayersIdentity */ PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id) @@ -711,10 +712,10 @@ PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity i PRFileDesc *layer = fd; if (PR_TOP_IO_LAYER == id) { - if (PR_IO_LAYER_HEAD == fd->identity) - return fd->lower; - else - return fd; + if (PR_IO_LAYER_HEAD == fd->identity) { + return fd->lower; + } + return fd; } for (layer = fd; layer != NULL; layer = layer->lower) diff --git a/nsprpub/pr/src/io/prmmap.c b/nsprpub/pr/src/io/prmmap.c index 6ffc13305..64f7ed4e8 100644 --- a/nsprpub/pr/src/io/prmmap.c +++ b/nsprpub/pr/src/io/prmmap.c @@ -24,17 +24,16 @@ PR_IMPLEMENT(PRFileMap *) PR_CreateFileMap( || prot == PR_PROT_WRITECOPY); fmap = PR_NEWZAP(PRFileMap); if (NULL == fmap) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; } fmap->fd = fd; fmap->prot = prot; if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) { - return fmap; - } else { + return fmap; + } PR_DELETE(fmap); return NULL; - } } PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void) diff --git a/nsprpub/pr/src/io/prscanf.c b/nsprpub/pr/src/io/prscanf.c index 9d75d824e..377a6e643 100644 --- a/nsprpub/pr/src/io/prscanf.c +++ b/nsprpub/pr/src/io/prscanf.c @@ -409,7 +409,8 @@ Convert(ScanfState *state, const char *fmt) ch = GET(state); if (ch == EOF) { return NULL; - } else if (state->assign) { + } + if (state->assign) { *cArg++ = ch; } } @@ -602,10 +603,9 @@ StringGetChar(void *stream) if (*cPtr == '\0') { return EOF; - } else { - *((char **) stream) = cPtr + 1; - return (unsigned char) *cPtr; } + *((char **) stream) = cPtr + 1; + return (unsigned char) *cPtr; } static void diff --git a/nsprpub/pr/src/io/prsocket.c b/nsprpub/pr/src/io/prsocket.c index be9702408..a24b8e1bb 100644 --- a/nsprpub/pr/src/io/prsocket.c +++ b/nsprpub/pr/src/io/prsocket.c @@ -7,6 +7,12 @@ #include <string.h> +#if defined(_WIN64) +#ifndef SO_UPDATE_CONNECT_CONTEXT +#define SO_UPDATE_CONNECT_CONTEXT 0x7010 +#endif +#endif + /************************************************************************/ /* These two functions are only used in assertions. */ @@ -304,6 +310,48 @@ static PRStatus PR_CALLBACK SocketConnectContinue( } PR_ASSERT(out_flags & PR_POLL_WRITE); + +#if defined(_WIN64) + if (fd->secret->alreadyConnected) { + fd->secret->alreadyConnected = PR_FALSE; + } + /* TCP Fast Open on Windows must use ConnectEx, which uses overlapped + * input/output. + * To get result we need to use GetOverlappedResult. */ + if (fd->secret->overlappedActive) { + PR_ASSERT(fd->secret->nonblocking); + PRInt32 rvSent; + if (GetOverlappedResult(osfd, &fd->secret->ol, &rvSent, FALSE) == TRUE) { + fd->secret->overlappedActive = PR_FALSE; + PR_LOG(_pr_io_lm, PR_LOG_MIN, + ("SocketConnectContinue GetOverlappedResult succeeded\n")); + /* When ConnectEx is used, all previously set socket options and + * property are not enabled and to enable them + * SO_UPDATE_CONNECT_CONTEXT option need to be set. */ + if (setsockopt((SOCKET)osfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) != 0) { + err = WSAGetLastError(); + PR_LOG(_pr_io_lm, PR_LOG_MIN, + ("SocketConnectContinue setting SO_UPDATE_CONNECT_CONTEXT failed %d\n", err)); + _PR_MD_MAP_SETSOCKOPT_ERROR(err); + return PR_FAILURE; + } + return PR_SUCCESS; + } else { + err = WSAGetLastError(); + PR_LOG(_pr_io_lm, PR_LOG_MIN, + ("SocketConnectContinue GetOverlappedResult failed %d\n", err)); + if (err != ERROR_IO_INCOMPLETE) { + _PR_MD_MAP_CONNECT_ERROR(err); + fd->secret->overlappedActive = PR_FALSE; + return PR_FAILURE; + } else { + PR_SetError(PR_IN_PROGRESS_ERROR, 0); + return PR_FAILURE; + } + } + } +#endif + return PR_SUCCESS; #elif defined(XP_OS2) @@ -751,7 +799,7 @@ static PRInt32 PR_CALLBACK SocketSendTo( #endif count = 0; - while (amount > 0) { + do { temp = _PR_MD_SENDTO(fd, buf, amount, flags, addrp, PR_NETADDR_SIZE(addr), timeout); if (temp < 0) { @@ -764,10 +812,60 @@ static PRInt32 PR_CALLBACK SocketSendTo( } buf = (const void*) ((const char*)buf + temp); amount -= temp; - } + } while (amount > 0); return count; } +#if defined(_WIN64) && defined(WIN95) +static PRInt32 PR_CALLBACK SocketTCPSendTo( + PRFileDesc *fd, const void *buf, PRInt32 amount, + PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout) +{ + PRInt32 temp, count; + const PRNetAddr *addrp = addr; +#if defined(_PR_INET6) + PRNetAddr addrCopy; +#endif + PRThread *me = _PR_MD_CURRENT_THREAD(); + + if (_PR_PENDING_INTERRUPT(me)) { + me->flags &= ~_PR_INTERRUPT; + PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); + return -1; + } + if (_PR_IO_PENDING(me)) { + PR_SetError(PR_IO_PENDING_ERROR, 0); + return -1; + } + + PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); +#if defined(_PR_INET6) + if (addr->raw.family == PR_AF_INET6) { + addrCopy = *addr; + addrCopy.raw.family = AF_INET6; + addrp = &addrCopy; + } +#endif + + count = 0; + while (amount > 0) { + temp = _PR_MD_TCPSENDTO(fd, buf, amount, flags, + addrp, PR_NETADDR_SIZE(addr), timeout); + if (temp < 0) { + count = -1; + break; + } + count += temp; + if (fd->secret->nonblocking) { + break; + } + buf = (const void*) ((const char*)buf + temp); + amount -= temp; + } + return count; +} +#endif + static PRInt32 PR_CALLBACK SocketRecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout) { @@ -1066,6 +1164,15 @@ static PRInt16 PR_CALLBACK SocketPoll( PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) { *out_flags = 0; + +#if defined(_WIN64) + if (in_flags & PR_POLL_WRITE) { + if (fd->secret->alreadyConnected) { + out_flags = PR_POLL_WRITE; + return PR_POLL_WRITE; + } + } +#endif return in_flags; } /* SocketPoll */ @@ -1090,7 +1197,11 @@ static PRIOMethods tcpMethods = { SocketRecv, SocketSend, (PRRecvfromFN)_PR_InvalidInt, +#if defined(_WIN64) && defined(WIN95) + SocketTCPSendTo, /* This is for fast open. We imitate Linux interface. */ +#else (PRSendtoFN)_PR_InvalidInt, +#endif SocketPoll, SocketAcceptRead, SocketTransmitFile, |