mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-01 04:12:07 +00:00
task #14420 (Remove sys_sem_signal from inside SYS_ARCH_PROTECT crit section) done for LWIP_TCPIP_CORE_LOCKING==1
This commit is contained in:
parent
26d3466f50
commit
92997756d1
@ -32,6 +32,10 @@ HISTORY
|
|||||||
|
|
||||||
++ Bugfixes:
|
++ Bugfixes:
|
||||||
|
|
||||||
|
2017-04-11: Simon Goldschmidt
|
||||||
|
* sockets.c: task #14420 (Remove sys_sem_signal from inside SYS_ARCH_PROTECT
|
||||||
|
crit section) done for LWIP_TCPIP_CORE_LOCKING==1
|
||||||
|
|
||||||
2017-03-01: Simon Goldschmidt
|
2017-03-01: Simon Goldschmidt
|
||||||
* httpd: LWIP_HTTPD_POST_MANUAL_WND: fixed double-free when httpd_post_data_recved
|
* httpd: LWIP_HTTPD_POST_MANUAL_WND: fixed double-free when httpd_post_data_recved
|
||||||
is called nested from httpd_post_receive_data() (bug #50424)
|
is called nested from httpd_post_receive_data() (bug #50424)
|
||||||
|
@ -305,6 +305,17 @@ static void lwip_socket_drop_registered_memberships(int s);
|
|||||||
static struct lwip_sock sockets[NUM_SOCKETS];
|
static struct lwip_sock sockets[NUM_SOCKETS];
|
||||||
|
|
||||||
#if LWIP_SOCKET_SELECT
|
#if LWIP_SOCKET_SELECT
|
||||||
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
|
/* protect the select_cb_list using core lock */
|
||||||
|
#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev)
|
||||||
|
#define LWIP_SOCKET_SELECT_PROTECT(lev) LOCK_TCPIP_CORE()
|
||||||
|
#define LWIP_SOCKET_SELECT_UNPROTECT(lev) UNLOCK_TCPIP_CORE()
|
||||||
|
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||||
|
/* protect the select_cb_list using SYS_LIGHTWEIGHT_PROT */
|
||||||
|
#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev)
|
||||||
|
#define LWIP_SOCKET_SELECT_PROTECT(lev) SYS_ARCH_PROTECT(lev)
|
||||||
|
#define LWIP_SOCKET_SELECT_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev)
|
||||||
|
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||||
/** The global list of tasks waiting for select */
|
/** The global list of tasks waiting for select */
|
||||||
static struct lwip_select_cb *select_cb_list;
|
static struct lwip_select_cb *select_cb_list;
|
||||||
/** This counter is increased from lwip_select when the list is changed
|
/** This counter is increased from lwip_select when the list is changed
|
||||||
@ -600,10 +611,12 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
|||||||
SYS_ARCH_UNPROTECT(lev);
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
|
||||||
if (newconn->callback) {
|
if (newconn->callback) {
|
||||||
|
LOCK_TCPIP_CORE();
|
||||||
while(recvevent > 0) {
|
while(recvevent > 0) {
|
||||||
recvevent--;
|
recvevent--;
|
||||||
newconn->callback(newconn, NETCONN_EVT_RCVPLUS, 0);
|
newconn->callback(newconn, NETCONN_EVT_RCVPLUS, 0);
|
||||||
}
|
}
|
||||||
|
UNLOCK_TCPIP_CORE();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note that POSIX only requires us to check addr is non-NULL. addrlen must
|
/* Note that POSIX only requires us to check addr is non-NULL. addrlen must
|
||||||
@ -877,7 +890,9 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
|
|||||||
if (err == ERR_CLSD) {
|
if (err == ERR_CLSD) {
|
||||||
/* closed but already received data, ensure select gets the FIN, too */
|
/* closed but already received data, ensure select gets the FIN, too */
|
||||||
if (sock->conn->callback != NULL) {
|
if (sock->conn->callback != NULL) {
|
||||||
|
LOCK_TCPIP_CORE();
|
||||||
sock->conn->callback(sock->conn, NETCONN_EVT_RCVPLUS, 0);
|
sock->conn->callback(sock->conn, NETCONN_EVT_RCVPLUS, 0);
|
||||||
|
UNLOCK_TCPIP_CORE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto lwip_recv_tcp_done;
|
goto lwip_recv_tcp_done;
|
||||||
@ -1778,6 +1793,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
fd_set used_sockets;
|
fd_set used_sockets;
|
||||||
#endif
|
#endif
|
||||||
SYS_ARCH_DECL_PROTECT(lev);
|
SYS_ARCH_DECL_PROTECT(lev);
|
||||||
|
LWIP_SOCKET_SELECT_DECL_PROTECT(lev2);
|
||||||
|
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n",
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n",
|
||||||
maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
|
maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
|
||||||
@ -1832,7 +1848,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||||
|
|
||||||
/* Protect the select_cb_list */
|
/* Protect the select_cb_list */
|
||||||
SYS_ARCH_PROTECT(lev);
|
LWIP_SOCKET_SELECT_PROTECT(lev2);
|
||||||
|
|
||||||
/* Put this select_cb on top of list */
|
/* Put this select_cb on top of list */
|
||||||
select_cb.next = select_cb_list;
|
select_cb.next = select_cb_list;
|
||||||
@ -1844,7 +1860,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
select_cb_ctr++;
|
select_cb_ctr++;
|
||||||
|
|
||||||
/* Now we can safely unprotect */
|
/* Now we can safely unprotect */
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
LWIP_SOCKET_SELECT_UNPROTECT(lev2);
|
||||||
|
|
||||||
/* Increase select_waiting for each socket we are interested in */
|
/* Increase select_waiting for each socket we are interested in */
|
||||||
maxfdp2 = maxfdp1;
|
maxfdp2 = maxfdp1;
|
||||||
@ -1917,7 +1933,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Take us off the list */
|
/* Take us off the list */
|
||||||
SYS_ARCH_PROTECT(lev);
|
LWIP_SOCKET_SELECT_PROTECT(lev2);
|
||||||
if (select_cb.next != NULL) {
|
if (select_cb.next != NULL) {
|
||||||
select_cb.next->prev = select_cb.prev;
|
select_cb.next->prev = select_cb.prev;
|
||||||
}
|
}
|
||||||
@ -1930,7 +1946,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||||||
}
|
}
|
||||||
/* Increasing this counter tells event_callback that the list has changed. */
|
/* Increasing this counter tells event_callback that the list has changed. */
|
||||||
select_cb_ctr++;
|
select_cb_ctr++;
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
LWIP_SOCKET_SELECT_UNPROTECT(lev2);
|
||||||
|
|
||||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||||
if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) {
|
if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) {
|
||||||
@ -2058,7 +2074,9 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
|||||||
of waiting select calls + 1. This list is expected to be small. */
|
of waiting select calls + 1. This list is expected to be small. */
|
||||||
|
|
||||||
/* At this point, SYS_ARCH is still protected! */
|
/* At this point, SYS_ARCH is still protected! */
|
||||||
|
#if !LWIP_TCPIP_CORE_LOCKING
|
||||||
again:
|
again:
|
||||||
|
#endif
|
||||||
for (scb = select_cb_list; scb != NULL; scb = scb->next) {
|
for (scb = select_cb_list; scb != NULL; scb = scb->next) {
|
||||||
/* remember the state of select_cb_list to detect changes */
|
/* remember the state of select_cb_list to detect changes */
|
||||||
last_select_cb_ctr = select_cb_ctr;
|
last_select_cb_ctr = select_cb_ctr;
|
||||||
@ -2083,19 +2101,30 @@ again:
|
|||||||
}
|
}
|
||||||
if (do_signal) {
|
if (do_signal) {
|
||||||
scb->sem_signalled = 1;
|
scb->sem_signalled = 1;
|
||||||
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
|
/* We are called with core lock held, so we can unlock interrupts here
|
||||||
|
(last_select_cb_ctr is protected by core lock) */
|
||||||
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
#else
|
||||||
/* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might
|
/* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might
|
||||||
lead to the select thread taking itself off the list, invalidating the semaphore. */
|
lead to the select thread taking itself off the list, invalidating the semaphore. */
|
||||||
|
#endif
|
||||||
sys_sem_signal(SELECT_SEM_PTR(scb->sem));
|
sys_sem_signal(SELECT_SEM_PTR(scb->sem));
|
||||||
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
|
SYS_ARCH_PROTECT(lev);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* unlock interrupts with each step */
|
/* unlock interrupts with each step */
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
/* this makes sure interrupt protection time is short */
|
/* this makes sure interrupt protection time is short */
|
||||||
SYS_ARCH_PROTECT(lev);
|
SYS_ARCH_PROTECT(lev);
|
||||||
|
#if !LWIP_TCPIP_CORE_LOCKING
|
||||||
if (last_select_cb_ctr != select_cb_ctr) {
|
if (last_select_cb_ctr != select_cb_ctr) {
|
||||||
/* someone has changed select_cb_list, restart at the beginning */
|
/* someone has changed select_cb_list, restart at the beginning */
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
done_socket(sock);
|
done_socket(sock);
|
||||||
|
Loading…
Reference in New Issue
Block a user