Bugzilla bug #40778: added new function PR_ConnectContinue and new

I/O method connectcontinue.  Deprecate PR_GetConnectStatus and define
it in terms of PR_ConnectContinue.
Modified files: prio.h, prfile.c, priometh.c, prlayer.c, prpolevt.c,
prsocket.c, ptio.c
This commit is contained in:
wtc%netscape.com 2000-06-02 02:07:56 +00:00
Родитель c45b91dd46
Коммит 8eafdae117
7 изменённых файлов: 115 добавлений и 40 удалений

Просмотреть файл

@ -345,6 +345,8 @@ typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)(
typedef PRInt32 (PR_CALLBACK *PRSendfileFN)(
PRFileDesc *networkSocket, PRSendFileData *sendData,
PRTransmitFileFlags flags, PRIntervalTime timeout);
typedef PRStatus (PR_CALLBACK *PRConnectcontinueFN)(
PRFileDesc *fd, PRInt16 out_flags);
typedef PRIntn (PR_CALLBACK *PRReservedFN)(PRFileDesc *fd);
struct PRIOMethods {
@ -381,7 +383,8 @@ struct PRIOMethods {
PRSetsocketoptionFN setsocketoption;
/* Set value of specified option */
PRSendfileFN sendfile; /* Send a (partial) file with header/trailer*/
PRReservedFN reserved_fn_4; /* reserved for future use */
PRConnectcontinueFN connectcontinue;
/* Continue a nonblocking connect */
PRReservedFN reserved_fn_3; /* reserved for future use */
PRReservedFN reserved_fn_2; /* reserved for future use */
PRReservedFN reserved_fn_1; /* reserved for future use */
@ -1202,6 +1205,42 @@ NSPR_API(PRStatus) PR_Connect(
/*
*************************************************************************
* FUNCTION: PR_ConnectContinue
* DESCRIPTION:
* Continue a nonblocking connect. After a nonblocking connect
* is initiated with PR_Connect() (which fails with
* PR_IN_PROGRESS_ERROR), one should call PR_Poll() on the socket,
* with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT. When
* PR_Poll() returns, one calls PR_ConnectContinue() on the
* socket to determine whether the nonblocking connect has
* completed or is still in progress. Repeat the PR_Poll(),
* PR_ConnectContinue() sequence until the nonblocking connect
* has completed.
* INPUTS:
* PRFileDesc *fd
* the file descriptor representing a socket
* PRInt16 out_flags
* the out_flags field of the poll descriptor returned by
* PR_Poll()
* RETURN: PRStatus
* If the nonblocking connect has successfully completed,
* PR_GetConnectStatus returns PR_SUCCESS. If PR_GetConnectStatus()
* returns PR_FAILURE, call PR_GetError():
* - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in
* progress and has not completed yet. The caller should poll
* on the file descriptor for the in_flags
* PR_POLL_WRITE|PR_POLL_EXCEPT and retry PR_ConnectContinue
* later when PR_Poll() returns.
* - Other errors: the nonblocking connect has failed with this
* error code.
*/
NSPR_API(PRStatus) PR_ConnectContinue(PRFileDesc *fd, PRInt16 out_flags);
/*
*************************************************************************
* THIS FUNCTION IS DEPRECATED. USE PR_ConnectContinue INSTEAD.
*
* FUNCTION: PR_GetConnectStatus
* DESCRIPTION:
* Get the completion status of a nonblocking connect. After

Просмотреть файл

@ -273,7 +273,7 @@ static PRIOMethods _pr_fileMethods = {
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
@ -317,7 +317,7 @@ static PRIOMethods _pr_pipeMethods = {
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,

Просмотреть файл

@ -53,7 +53,7 @@ PRIOMethods _pr_faulty_methods = {
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
@ -166,6 +166,12 @@ PR_IMPLEMENT(PRStatus) PR_Connect(
return((fd->methods->connect)(fd,addr,timeout));
}
PR_IMPLEMENT(PRStatus) PR_ConnectContinue(
PRFileDesc *fd, PRInt16 out_flags)
{
return((fd->methods->connectcontinue)(fd,out_flags));
}
PR_IMPLEMENT(PRFileDesc*) PR_Accept(PRFileDesc *fd, PRNetAddr *addr,
PRIntervalTime timeout)
{

Просмотреть файл

@ -175,6 +175,15 @@ static PRStatus PR_CALLBACK pl_DefConnect (
return (fd->lower->methods->connect)(fd->lower, addr, timeout);
}
static PRStatus PR_CALLBACK pl_DefConnectcontinue (
PRFileDesc *fd, PRInt16 out_flags)
{
PR_ASSERT(fd != NULL);
PR_ASSERT(fd->lower != NULL);
return (fd->lower->methods->connectcontinue)(fd->lower, out_flags);
}
static PRFileDesc* PR_CALLBACK pl_TopAccept (
PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
{
@ -427,7 +436,7 @@ static PRIOMethods pl_methods = {
pl_DefGetsocketoption,
pl_DefSetsocketoption,
pl_DefSendfile,
(PRReservedFN)_PR_InvalidInt,
pl_DefConnectcontinue,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,

Просмотреть файл

@ -174,7 +174,7 @@ static PRIOMethods _pr_polevt_methods = {
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,

Просмотреть файл

@ -253,26 +253,23 @@ static PRStatus PR_CALLBACK SocketConnect(
return PR_FAILURE;
}
PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
static PRStatus PR_CALLBACK SocketConnectContinue(
PRFileDesc *fd, PRInt16 out_flags)
{
PRInt32 osfd;
PRFileDesc *bottom = pd->fd;
int err;
if (pd->out_flags & PR_POLL_NVAL) {
if (out_flags & PR_POLL_NVAL) {
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
return PR_FAILURE;
}
if ((pd->out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) {
PR_ASSERT(pd->out_flags == 0);
if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) {
PR_ASSERT(out_flags == 0);
PR_SetError(PR_IN_PROGRESS_ERROR, 0);
return PR_FAILURE;
}
while (bottom->lower != NULL) {
bottom = bottom->lower;
}
osfd = bottom->secret->md.osfd;
osfd = fd->secret->md.osfd;
#if defined(XP_UNIX)
@ -293,7 +290,7 @@ PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
Sleep(0);
#endif /* WIN32 */
if (pd->out_flags & PR_POLL_EXCEPT) {
if (out_flags & PR_POLL_EXCEPT) {
int len = sizeof(err);
if (getsockopt(osfd, (int)SOL_SOCKET, SO_ERROR, (char *) &err, &len)
== SOCKET_ERROR) {
@ -308,12 +305,12 @@ PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
return PR_FAILURE;
}
PR_ASSERT(pd->out_flags & PR_POLL_WRITE);
PR_ASSERT(out_flags & PR_POLL_WRITE);
return PR_SUCCESS;
#elif defined(XP_OS2)
if (pd->out_flags & PR_POLL_EXCEPT) {
if (out_flags & PR_POLL_EXCEPT) {
int len = sizeof(err);
if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len)
< 0) {
@ -328,7 +325,7 @@ PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
return PR_FAILURE;
}
PR_ASSERT(pd->out_flags & PR_POLL_WRITE);
PR_ASSERT(out_flags & PR_POLL_WRITE);
return PR_SUCCESS;
#elif defined(XP_MAC)
@ -341,7 +338,7 @@ PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
#elif defined(XP_BEOS)
err = _MD_beos_get_nonblocking_connect_error(bottom);
err = _MD_beos_get_nonblocking_connect_error(fd);
if( err != 0 ) {
_PR_MD_MAP_CONNECT_ERROR(err);
return PR_FAILURE;
@ -355,6 +352,18 @@ PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
#endif
}
PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
{
/* Find the NSPR layer and invoke its connectcontinue method */
PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
if (NULL == bottom) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
}
return bottom->methods->connectcontinue(pd->fd, pd->out_flags);
}
static PRFileDesc* PR_CALLBACK SocketAccept(PRFileDesc *fd, PRNetAddr *addr,
PRIntervalTime timeout)
{
@ -1105,7 +1114,7 @@ static PRIOMethods tcpMethods = {
_PR_SocketGetSocketOption,
_PR_SocketSetSocketOption,
SocketSendFile,
(PRReservedFN)_PR_InvalidInt,
SocketConnectContinue;
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
@ -1144,7 +1153,7 @@ static PRIOMethods udpMethods = {
_PR_SocketGetSocketOption,
_PR_SocketSetSocketOption,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
@ -1184,7 +1193,7 @@ static PRIOMethods socketpollfdMethods = {
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,

Просмотреть файл

@ -1348,35 +1348,47 @@ static PRStatus pt_Connect(
return PR_SUCCESS;
} /* pt_Connect */
PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
static PRStatus pt_ConnectContinue(
PRFileDesc *fd, PRInt16 out_flags)
{
int err;
PRInt32 osfd;
PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
if (NULL == bottom) {
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
}
if (pd->out_flags & PR_POLL_NVAL) {
if (out_flags & PR_POLL_NVAL)
{
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
return PR_FAILURE;
}
if ((pd->out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) {
PR_ASSERT(pd->out_flags == 0);
if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0)
{
PR_ASSERT(out_flags == 0);
PR_SetError(PR_IN_PROGRESS_ERROR, 0);
return PR_FAILURE;
}
osfd = bottom->secret->md.osfd;
osfd = fd->secret->md.osfd;
err = _MD_unix_get_nonblocking_connect_error(osfd);
if (err != 0) {
if (err != 0)
{
_PR_MD_MAP_CONNECT_ERROR(err);
return PR_FAILURE;
}
return PR_SUCCESS;
}
} /* pt_ConnectContinue */
PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
{
/* Find the NSPR layer and invoke its connectcontinue method */
PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
if (NULL == bottom)
{
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return PR_FAILURE;
}
return bottom->methods->connectcontinue(pd->fd, pd->out_flags);
} /* PR_GetConnectStatus */
static PRFileDesc* pt_Accept(
PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
@ -2455,7 +2467,7 @@ static PRIOMethods _pr_file_methods = {
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
@ -2494,7 +2506,7 @@ static PRIOMethods _pr_pipe_methods = {
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
@ -2533,7 +2545,7 @@ static PRIOMethods _pr_tcp_methods = {
pt_GetSocketOption,
pt_SetSocketOption,
pt_SendFile,
(PRReservedFN)_PR_InvalidInt,
pt_ConnectContinue,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
@ -2572,7 +2584,7 @@ static PRIOMethods _pr_udp_methods = {
pt_GetSocketOption,
pt_SetSocketOption,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
@ -2611,7 +2623,7 @@ static PRIOMethods _pr_socketpollfd_methods = {
(PRGetsocketoptionFN)_PR_InvalidStatus,
(PRSetsocketoptionFN)_PR_InvalidStatus,
(PRSendfileFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRConnectcontinueFN)_PR_InvalidStatus,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,
(PRReservedFN)_PR_InvalidInt,