Asynchronous connect (for non-blocking socket connect emulation)

This commit is contained in:
Philip Homburg 2005-09-30 12:44:39 +00:00
parent a9a8299e88
commit 5f7b803dcd
2 changed files with 91 additions and 6 deletions

View file

@ -36,6 +36,11 @@ typedef struct nwio_tcpcl
long nwtcl_ttl;
} nwio_tcpcl_t;
#define TCF_DEFAULT 0 /* Default parameters */
#define TCF_ASYNCH 1 /* Asynchronous connect for non-blocking
* socket emulation.
*/
typedef struct nwio_tcpatt
{
long nwta_flags;

View file

@ -284,6 +284,13 @@ unsigned operations;
return ENOTCONN; /* Is this right? */
return resops;
}
if (tcp_fd->tf_flags & TFF_CONNECTING)
{
/* Special case for CONNECTING */
if (operations & SR_SELECT_WRITE)
tcp_fd->tf_flags |= TFF_SEL_WRITE;
return 0;
}
if (operations & SR_SELECT_READ)
{
if (!(tcp_fd->tf_flags & TFF_CONNECTEDx))
@ -807,7 +814,12 @@ assert (conf_acc->acc_length == sizeof(*tcp_conf));
break;
case NWIOTCPCONN:
if (tcp_fd->tf_flags & TFF_CONNECTING)
assert(NOT_IMPLEMENTED);
{
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
reply_thr_get (tcp_fd, EALREADY, TRUE);
result= NW_OK;
break;
}
if (tcp_fd->tf_flags & TFF_CONNECTEDx)
{
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
@ -816,6 +828,8 @@ assert (conf_acc->acc_length == sizeof(*tcp_conf));
break;
}
result= tcp_connect(tcp_fd);
if (result == NW_OK)
tcp_fd->tf_flags &= ~TFF_IOCTL_IP;
break;
case NWIOTCPLISTEN:
case NWIOTCPLISTENQ:
@ -1839,10 +1853,6 @@ tcp_conn_t *tcp_conn;
return;
}
assert(tcp_fd->tf_flags & TFF_IOCTL_IP);
assert(tcp_fd->tf_ioreq == NWIOTCPLISTEN ||
tcp_fd->tf_ioreq == NWIOTCPCONN);
if (tcp_conn->tc_state == TCS_CLOSED)
{
reply= tcp_conn->tc_error;
@ -1855,6 +1865,28 @@ tcp_conn_t *tcp_conn;
tcp_fd->tf_flags |= TFF_CONNECTEDx;
reply= NW_OK;
}
if (tcp_fd->tf_flags & TFF_CONNECTING)
{
/* Special code for asynchronous connects */
tcp_fd->tf_flags &= ~TFF_CONNECTING;
/* Reply for select */
if ((tcp_fd->tf_flags & TFF_SEL_WRITE) &&
tcp_fd->tf_select_res)
{
tcp_fd->tf_flags &= ~TFF_SEL_WRITE;
tcp_fd->tf_select_res(tcp_fd->tf_srfd,
SR_SELECT_WRITE);
}
return;
}
assert(tcp_fd->tf_flags & TFF_IOCTL_IP);
assert(tcp_fd->tf_ioreq == NWIOTCPLISTEN ||
tcp_fd->tf_ioreq == NWIOTCPCONN);
tcp_reply_ioctl (tcp_fd, reply);
}
@ -1920,10 +1952,25 @@ int fd;
assert(tcp_fd->tf_listenq[i] == NULL);
}
if (tcp_fd->tf_flags & TFF_CONNECTING)
{
tcp_conn= tcp_fd->tf_conn;
assert(tcp_conn != NULL);
assert (tcp_conn->tc_connInprogress);
tcp_conn->tc_connInprogress= 0;
tcp_conn->tc_fd= NULL;
tcp_fd->tf_conn= NULL;
tcp_close_connection(tcp_conn, ENOCONN);
tcp_fd->tf_flags &= ~TFF_CONNECTING;
}
tcp_fd->tf_flags &= ~TFF_INUSE;
if (!tcp_fd->tf_conn)
return;
tcp_conn= tcp_fd->tf_conn;
assert(tcp_conn->tc_fd == tcp_fd);
tcp_conn->tc_fd= NULL;
@ -2020,6 +2067,10 @@ PRIVATE int tcp_connect(tcp_fd)
tcp_fd_t *tcp_fd;
{
tcp_conn_t *tcp_conn;
nwio_tcpcl_t *tcpcl;
long nwtcl_flags;
int r, do_asynch;
acc_t *data;
if (!(tcp_fd->tf_flags & TFF_CONF_SET))
{
@ -2036,6 +2087,28 @@ tcp_fd_t *tcp_fd;
return NW_OK;
}
data= (*tcp_fd->tf_get_userdata) (tcp_fd->tf_srfd, 0,
sizeof(*tcpcl), TRUE);
if (!data)
return EFAULT;
data= bf_packIffLess(data, sizeof(*tcpcl));
assert (data->acc_length == sizeof(*tcpcl));
tcpcl= (nwio_tcpcl_t *)ptr2acc_data(data);
nwtcl_flags= tcpcl->nwtcl_flags;
bf_afree(data); data= NULL; tcpcl= NULL;
if (nwtcl_flags == TCF_ASYNCH)
do_asynch= 1;
else if (nwtcl_flags == TCF_DEFAULT)
do_asynch= 0;
else
{
tcp_reply_ioctl(tcp_fd, EINVAL);
return NW_OK;
}
assert(!tcp_fd->tf_conn);
tcp_conn= find_conn_entry(tcp_fd->tf_tcpconf.nwtc_locport,
tcp_fd->tf_port->tp_ipaddr,
@ -2060,7 +2133,14 @@ tcp_fd_t *tcp_fd;
}
tcp_fd->tf_conn= tcp_conn;
return tcp_su4connect(tcp_fd);
r= tcp_su4connect(tcp_fd);
if (r == NW_SUSPEND && do_asynch)
{
tcp_fd->tf_flags |= TFF_CONNECTING;
tcp_reply_ioctl(tcp_fd, EINPROGRESS);
r= NW_OK;
}
return r;
}
/*