mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 14:29:39 +00:00
Added except set support in select (patch #6860)
This commit is contained in:
parent
9c41e1eea3
commit
855dcadf7a
@ -19,6 +19,10 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
|
||||
* api.h, api_msg.c, sockets.c: Added except set support in select
|
||||
(patch #6860)
|
||||
|
||||
2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
|
||||
* api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c:
|
||||
Add non-blocking support for connect (partly from patch #6860),
|
||||
|
@ -330,7 +330,7 @@ err_tcp(void *arg, err_t err)
|
||||
|
||||
conn->pcb.tcp = NULL;
|
||||
|
||||
/* no check since this is always fatal */
|
||||
/* no check since this is always fatal! */
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
conn->last_err = err;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
@ -339,18 +339,25 @@ err_tcp(void *arg, err_t err)
|
||||
old_state = conn->state;
|
||||
conn->state = NETCONN_NONE;
|
||||
|
||||
/* Notify the user layer about a connection error. Used to signal
|
||||
select. */
|
||||
API_EVENT(conn, NETCONN_EVT_ERROR, 0);
|
||||
/* Try to release selects pending on 'read' or 'write', too.
|
||||
They will get an error if they actually try to read or write. */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
|
||||
/* pass NULL-message to recvmbox to wake up pending recv */
|
||||
if (conn->recvmbox != SYS_MBOX_NULL) {
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||
/* use trypot to preven deadlock */
|
||||
/* use trypost to prevent deadlock */
|
||||
sys_mbox_trypost(conn->recvmbox, NULL);
|
||||
}
|
||||
/* pass NULL-message to acceptmbox to wake up pending accept */
|
||||
if (conn->acceptmbox != SYS_MBOX_NULL) {
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||
/* use trypot to preven deadlock */
|
||||
/* use trypost to preven deadlock */
|
||||
sys_mbox_trypost(conn->acceptmbox, NULL);
|
||||
}
|
||||
|
||||
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
|
||||
(old_state == NETCONN_CONNECT)) {
|
||||
/* calling do_writemore/do_close_internal is not necessary
|
||||
@ -721,8 +728,9 @@ do_close_internal(struct netconn *conn)
|
||||
conn->state = NETCONN_NONE;
|
||||
/* Set back some callback pointers as conn is going away */
|
||||
conn->pcb.tcp = NULL;
|
||||
/* @todo: this lets select make the socket readable and writable,
|
||||
which is wrong! errfd instead? */
|
||||
/* Trigger select() in socket layer. Make sure everybody notices activity
|
||||
on the connection, error first! */
|
||||
API_EVENT(conn, NETCONN_EVT_ERROR, 0);
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
/* wake up the application task */
|
||||
|
@ -70,6 +70,8 @@ struct lwip_socket {
|
||||
/** number of times data was ACKed (free send buffer), set by event_callback(),
|
||||
tested by select */
|
||||
u16_t sendevent;
|
||||
/** error happened for this socket, set by event_callback(), tested by select */
|
||||
u16_t errevent;
|
||||
/** last error that occurred on this socket */
|
||||
int err;
|
||||
};
|
||||
@ -227,6 +229,7 @@ alloc_socket(struct netconn *newconn)
|
||||
sockets[i].rcvevent = 0;
|
||||
/* TCP sendbuf is empty, but not connected yet, so not yet writable */
|
||||
sockets[i].sendevent = (newconn->type == NETCONN_TCP ? 0 : 1);
|
||||
sockets[i].errevent = 0;
|
||||
sockets[i].err = 0;
|
||||
sys_sem_signal(socksem);
|
||||
return i;
|
||||
@ -872,10 +875,19 @@ lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
|
||||
nready++;
|
||||
}
|
||||
}
|
||||
if (FD_ISSET(i, exceptset)) {
|
||||
/* See if netconn of this socket had an error */
|
||||
p_sock = get_socket(i);
|
||||
if (p_sock && p_sock->errevent) {
|
||||
FD_SET(i, &lexceptset);
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i));
|
||||
nready++;
|
||||
}
|
||||
}
|
||||
}
|
||||
*readset = lreadset;
|
||||
*writeset = lwriteset;
|
||||
FD_ZERO(exceptset);
|
||||
*exceptset = lexceptset;
|
||||
|
||||
return nready;
|
||||
}
|
||||
@ -1087,6 +1099,9 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||
case NETCONN_EVT_SENDMINUS:
|
||||
sock->sendevent = 0;
|
||||
break;
|
||||
case NETCONN_EVT_ERROR:
|
||||
sock->errevent = 1;
|
||||
break;
|
||||
default:
|
||||
LWIP_ASSERT("unknown event", 0);
|
||||
break;
|
||||
@ -1111,6 +1126,9 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||
if (scb->writeset && FD_ISSET(s, scb->writeset))
|
||||
if (sock->sendevent)
|
||||
break;
|
||||
if (scb->exceptset && FD_ISSET(s, scb->exceptset))
|
||||
if (sock->errevent != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scb) {
|
||||
|
@ -89,7 +89,8 @@ enum netconn_evt {
|
||||
NETCONN_EVT_RCVPLUS,
|
||||
NETCONN_EVT_RCVMINUS,
|
||||
NETCONN_EVT_SENDPLUS,
|
||||
NETCONN_EVT_SENDMINUS
|
||||
NETCONN_EVT_SENDMINUS,
|
||||
NETCONN_EVT_ERROR
|
||||
};
|
||||
|
||||
#if LWIP_IGMP
|
||||
|
Loading…
Reference in New Issue
Block a user