mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-04-23 11:43:10 +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:
|
++ 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)
|
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:
|
* 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),
|
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;
|
conn->pcb.tcp = NULL;
|
||||||
|
|
||||||
/* no check since this is always fatal */
|
/* no check since this is always fatal! */
|
||||||
SYS_ARCH_PROTECT(lev);
|
SYS_ARCH_PROTECT(lev);
|
||||||
conn->last_err = err;
|
conn->last_err = err;
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
@ -339,18 +339,25 @@ err_tcp(void *arg, err_t err)
|
|||||||
old_state = conn->state;
|
old_state = conn->state;
|
||||||
conn->state = NETCONN_NONE;
|
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) {
|
if (conn->recvmbox != SYS_MBOX_NULL) {
|
||||||
/* Register event with callback */
|
/* use trypost to prevent deadlock */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
|
||||||
/* use trypot to preven deadlock */
|
|
||||||
sys_mbox_trypost(conn->recvmbox, NULL);
|
sys_mbox_trypost(conn->recvmbox, NULL);
|
||||||
}
|
}
|
||||||
|
/* pass NULL-message to acceptmbox to wake up pending accept */
|
||||||
if (conn->acceptmbox != SYS_MBOX_NULL) {
|
if (conn->acceptmbox != SYS_MBOX_NULL) {
|
||||||
/* Register event with callback */
|
/* use trypost to preven deadlock */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
|
||||||
/* use trypot to preven deadlock */
|
|
||||||
sys_mbox_trypost(conn->acceptmbox, NULL);
|
sys_mbox_trypost(conn->acceptmbox, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
|
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
|
||||||
(old_state == NETCONN_CONNECT)) {
|
(old_state == NETCONN_CONNECT)) {
|
||||||
/* calling do_writemore/do_close_internal is not necessary
|
/* calling do_writemore/do_close_internal is not necessary
|
||||||
@ -721,8 +728,9 @@ do_close_internal(struct netconn *conn)
|
|||||||
conn->state = NETCONN_NONE;
|
conn->state = NETCONN_NONE;
|
||||||
/* Set back some callback pointers as conn is going away */
|
/* Set back some callback pointers as conn is going away */
|
||||||
conn->pcb.tcp = NULL;
|
conn->pcb.tcp = NULL;
|
||||||
/* @todo: this lets select make the socket readable and writable,
|
/* Trigger select() in socket layer. Make sure everybody notices activity
|
||||||
which is wrong! errfd instead? */
|
on the connection, error first! */
|
||||||
|
API_EVENT(conn, NETCONN_EVT_ERROR, 0);
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||||
/* wake up the application task */
|
/* 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(),
|
/** number of times data was ACKed (free send buffer), set by event_callback(),
|
||||||
tested by select */
|
tested by select */
|
||||||
u16_t sendevent;
|
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 */
|
/** last error that occurred on this socket */
|
||||||
int err;
|
int err;
|
||||||
};
|
};
|
||||||
@ -227,6 +229,7 @@ alloc_socket(struct netconn *newconn)
|
|||||||
sockets[i].rcvevent = 0;
|
sockets[i].rcvevent = 0;
|
||||||
/* TCP sendbuf is empty, but not connected yet, so not yet writable */
|
/* TCP sendbuf is empty, but not connected yet, so not yet writable */
|
||||||
sockets[i].sendevent = (newconn->type == NETCONN_TCP ? 0 : 1);
|
sockets[i].sendevent = (newconn->type == NETCONN_TCP ? 0 : 1);
|
||||||
|
sockets[i].errevent = 0;
|
||||||
sockets[i].err = 0;
|
sockets[i].err = 0;
|
||||||
sys_sem_signal(socksem);
|
sys_sem_signal(socksem);
|
||||||
return i;
|
return i;
|
||||||
@ -872,10 +875,19 @@ lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
|
|||||||
nready++;
|
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;
|
*readset = lreadset;
|
||||||
*writeset = lwriteset;
|
*writeset = lwriteset;
|
||||||
FD_ZERO(exceptset);
|
*exceptset = lexceptset;
|
||||||
|
|
||||||
return nready;
|
return nready;
|
||||||
}
|
}
|
||||||
@ -1087,6 +1099,9 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
|||||||
case NETCONN_EVT_SENDMINUS:
|
case NETCONN_EVT_SENDMINUS:
|
||||||
sock->sendevent = 0;
|
sock->sendevent = 0;
|
||||||
break;
|
break;
|
||||||
|
case NETCONN_EVT_ERROR:
|
||||||
|
sock->errevent = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LWIP_ASSERT("unknown event", 0);
|
LWIP_ASSERT("unknown event", 0);
|
||||||
break;
|
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 (scb->writeset && FD_ISSET(s, scb->writeset))
|
||||||
if (sock->sendevent)
|
if (sock->sendevent)
|
||||||
break;
|
break;
|
||||||
|
if (scb->exceptset && FD_ISSET(s, scb->exceptset))
|
||||||
|
if (sock->errevent != 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (scb) {
|
if (scb) {
|
||||||
|
@ -89,7 +89,8 @@ enum netconn_evt {
|
|||||||
NETCONN_EVT_RCVPLUS,
|
NETCONN_EVT_RCVPLUS,
|
||||||
NETCONN_EVT_RCVMINUS,
|
NETCONN_EVT_RCVMINUS,
|
||||||
NETCONN_EVT_SENDPLUS,
|
NETCONN_EVT_SENDPLUS,
|
||||||
NETCONN_EVT_SENDMINUS
|
NETCONN_EVT_SENDMINUS,
|
||||||
|
NETCONN_EVT_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
#if LWIP_IGMP
|
#if LWIP_IGMP
|
||||||
|
Loading…
x
Reference in New Issue
Block a user