mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-07-15 08:32:42 +08:00
fix(lwip): Fix lwip multi-thread issue
internal: e7c378b6
This commit is contained in:
2
VERSION
2
VERSION
@ -13,7 +13,7 @@ gwen:
|
||||
gitlab:
|
||||
espconn: 3a998034
|
||||
freertos: ac047746
|
||||
lwip: 3c4f800b
|
||||
lwip: 829319d2
|
||||
driver: 7bee5263
|
||||
mbedtls: 1ac9f1f4
|
||||
ssl: eefb383a
|
BIN
lib/liblwip.a
BIN
lib/liblwip.a
Binary file not shown.
5
third_party/lwip/api/api_msg.c
vendored
5
third_party/lwip/api/api_msg.c
vendored
@ -295,7 +295,10 @@ poll_tcp(void *arg, struct tcp_pcb *pcb)
|
||||
lwip_netconn_do_writemore(conn);
|
||||
} else if (conn->state == NETCONN_CLOSE) {
|
||||
lwip_netconn_do_close_internal(conn);
|
||||
} else if (conn->state == NETCONN_NONE) {
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/* @todo: implement connect timeout here? */
|
||||
|
||||
/* Did a nonblocking write fail before? Then check available write-space. */
|
||||
@ -331,6 +334,8 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
|
||||
lwip_netconn_do_writemore(conn);
|
||||
} else if (conn->state == NETCONN_CLOSE) {
|
||||
lwip_netconn_do_close_internal(conn);
|
||||
} else if (conn->state == NETCONN_NONE) {
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
if (conn) {
|
||||
|
137
third_party/lwip/api/multi-threads/sockets_mt.c
vendored
137
third_party/lwip/api/multi-threads/sockets_mt.c
vendored
@ -66,6 +66,7 @@ typedef struct _sock_mt sock_mt_t;
|
||||
#define SOCK_MT_DEBUG(level, ...)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define SOCK_MT_LOCK(s, l) \
|
||||
{ \
|
||||
SOCK_MT_DEBUG(1, "s %d l %d enter ", s, l); \
|
||||
@ -73,6 +74,57 @@ typedef struct _sock_mt sock_mt_t;
|
||||
SOCK_MT_DEBUG(1, "OK\n"); \
|
||||
}
|
||||
|
||||
#define SOCK_MT_LOCK_RET(s, l, r) \
|
||||
{ \
|
||||
SOCK_MT_LOCK(s, l); \
|
||||
r = ERR_OK; \
|
||||
}
|
||||
#else
|
||||
#define SOCK_MT_LOCK(s, l) \
|
||||
{ \
|
||||
SOCK_MT_DEBUG(1, "s %d l %d enter ", s, l); \
|
||||
while (1) { \
|
||||
err_t err; \
|
||||
SYS_ARCH_DECL_PROTECT(lev); \
|
||||
\
|
||||
SYS_ARCH_PROTECT(lev); \
|
||||
if (sockets_mt[s].lock[l]) \
|
||||
err = sys_mutex_trylock(&sockets_mt[s].lock[l]); \
|
||||
else \
|
||||
err = ERR_VAL; \
|
||||
SYS_ARCH_UNPROTECT(lev); \
|
||||
\
|
||||
if (err == ERR_OK) \
|
||||
break; \
|
||||
else if (err == ERR_VAL) \
|
||||
return -1; \
|
||||
\
|
||||
vTaskDelay(1); \
|
||||
} \
|
||||
SOCK_MT_DEBUG(1, "OK\n"); \
|
||||
}
|
||||
|
||||
#define SOCK_MT_LOCK_RET(s, l, r) \
|
||||
{ \
|
||||
SOCK_MT_DEBUG(1, "s %d l %d enter ", s, l); \
|
||||
while (1) { \
|
||||
SYS_ARCH_DECL_PROTECT(lev); \
|
||||
\
|
||||
SYS_ARCH_PROTECT(lev); \
|
||||
if (sockets_mt[s].lock[l]) \
|
||||
r = sys_mutex_trylock(&sockets_mt[s].lock[l]); \
|
||||
else \
|
||||
r = ERR_VAL; \
|
||||
SYS_ARCH_UNPROTECT(lev); \
|
||||
\
|
||||
if (r == ERR_OK || ERR_VAL) \
|
||||
break; \
|
||||
vTaskDelay(1); \
|
||||
} \
|
||||
SOCK_MT_DEBUG(1, "OK\n"); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SOCK_MT_TRYLOCK(s, l, r) \
|
||||
{ \
|
||||
SOCK_MT_DEBUG(1, "s %d l %d try enter ", s, l); \
|
||||
@ -257,17 +309,21 @@ LOCAL int lwip_enter_mt_select(int s, int arg)
|
||||
goto failed1;
|
||||
|
||||
if (FD_ISSET(i, read_set)) {
|
||||
err_t err;
|
||||
|
||||
SOCK_MT_SET_READ_SEL(i);
|
||||
SOCK_MT_LOCK(i, SOCK_MT_RECV_LOCK);
|
||||
if (SOCK_MT_GET_SHUTDOWN(i) != SOCK_MT_SHUTDOWN_NONE) {
|
||||
SOCK_MT_LOCK_RET(i, SOCK_MT_RECV_LOCK, err);
|
||||
if (err != ERR_OK || SOCK_MT_GET_SHUTDOWN(i) != SOCK_MT_SHUTDOWN_NONE) {
|
||||
goto failed2;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(i, write_set)) {
|
||||
err_t err;
|
||||
|
||||
SOCK_MT_SET_WRITE_SEL(i);
|
||||
SOCK_MT_LOCK(i, SOCK_MT_STATE_LOCK);
|
||||
if (SOCK_MT_GET_SHUTDOWN(i) != SOCK_MT_SHUTDOWN_NONE) {
|
||||
SOCK_MT_LOCK_RET(i, SOCK_MT_STATE_LOCK, err);
|
||||
if (err != ERR_OK || SOCK_MT_GET_SHUTDOWN(i) != SOCK_MT_SHUTDOWN_NONE) {
|
||||
goto failed3;
|
||||
}
|
||||
}
|
||||
@ -408,6 +464,43 @@ LOCAL const ICACHE_RODATA_ATTR STORE_ATTR lwip_io_mt_fn lwip_exit_mt_table[] = {
|
||||
lwip_exit_mt_close
|
||||
};
|
||||
|
||||
LOCAL void lwip_do_sync_send(void *arg)
|
||||
{
|
||||
struct netconn *conn = arg;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (conn->current_msg) {
|
||||
conn->current_msg->err = ERR_OK;
|
||||
conn->current_msg = NULL;
|
||||
}
|
||||
conn->state = NETCONN_NONE;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
if (sys_sem_valid(&(conn->snd_op_completed)))
|
||||
sys_sem_signal(&(conn->snd_op_completed));
|
||||
|
||||
/*
|
||||
* if we use "op_completed" for its sync semaphore, then socket functions
|
||||
* which are blocked by op_completed will be waked up.
|
||||
*
|
||||
* So we had better use a specific semaphore for the function, ioctrl_completed
|
||||
* may be a good choise.
|
||||
*/
|
||||
sys_sem_signal(&(conn->ioctrl_completed));
|
||||
}
|
||||
|
||||
LOCAL void lwip_do_sync_rst_state(void *arg)
|
||||
{
|
||||
struct netconn *conn = arg;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
conn->state = NETCONN_NONE;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
sys_sem_signal(&(conn->ioctrl_completed));
|
||||
}
|
||||
|
||||
LOCAL void lwip_sync_state_mt(struct lwip_sock *sock , int state)
|
||||
{
|
||||
SOCK_MT_DEBUG(1, "sync state %d\n", state);
|
||||
@ -419,16 +512,8 @@ LOCAL void lwip_sync_state_mt(struct lwip_sock *sock , int state)
|
||||
break;
|
||||
case SOCK_MT_STATE_SEND :
|
||||
{
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (sock->conn->current_msg) {
|
||||
sock->conn->current_msg->err = ERR_OK;
|
||||
sock->conn->current_msg = NULL;
|
||||
}
|
||||
sock->conn->state = NETCONN_NONE;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
if (sys_sem_valid(&(sock->conn->snd_op_completed)))
|
||||
sys_sem_signal(&(sock->conn->snd_op_completed));
|
||||
tcpip_callback(lwip_do_sync_send, sock->conn);
|
||||
sys_arch_sem_wait(&sock->conn->ioctrl_completed, 0);
|
||||
break;
|
||||
}
|
||||
case SOCK_MT_STATE_CONNECT :
|
||||
@ -458,15 +543,19 @@ LOCAL void lwip_sync_mt(int s)
|
||||
{
|
||||
int module = 0;
|
||||
int ret;
|
||||
struct lwip_sock *sock;
|
||||
|
||||
while (module < SOCK_MT_SELECT) {
|
||||
extern void sys_arch_msleep(int ms);
|
||||
int ret;
|
||||
struct lwip_sock *sock;
|
||||
|
||||
SOCK_MT_TRYLOCK(s, module, ret);
|
||||
if (ret == ERR_OK) {
|
||||
SOCK_MT_UNLOCK(s, module);
|
||||
/*
|
||||
* we always lock the mutex in case of other thread entering,
|
||||
* other thread will be blocked at "SOCK_MT_LOCK" and poll-check
|
||||
*/
|
||||
//SOCK_MT_UNLOCK(s, module);
|
||||
module++;
|
||||
continue;
|
||||
}
|
||||
@ -494,6 +583,12 @@ LOCAL void lwip_sync_mt(int s)
|
||||
|
||||
sys_arch_msleep(LWIP_SYNC_MT_SLEEP_MS);
|
||||
}
|
||||
|
||||
sock = tryget_socket(s);
|
||||
if (sock) {
|
||||
tcpip_callback(lwip_do_sync_rst_state, sock->conn);
|
||||
sys_arch_sem_wait(&sock->conn->ioctrl_completed, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int lwip_socket_mt(int domain, int type, int protocol)
|
||||
@ -764,6 +859,8 @@ int lwip_close_mt(int s)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
sys_mutex_t lock_tmp[SOCK_MT_LOCK_MAX];
|
||||
|
||||
lwip_shutdown_mt(s, SHUT_RDWR);
|
||||
|
||||
@ -773,10 +870,16 @@ int lwip_close_mt(int s)
|
||||
|
||||
LWIP_EXIT_MT(s, SOCK_MT_CLOSE, 0);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
for (i = 0 ; i < SOCK_MT_LOCK_MAX; i++) {
|
||||
sys_mutex_free(&sockets_mt[s].lock[i]);
|
||||
lock_tmp[i] = sockets_mt[s].lock[i];
|
||||
sockets_mt[s].lock[i] = NULL;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
for (i = 0 ; i < SOCK_MT_LOCK_MAX; i++) {
|
||||
sys_mutex_free(&lock_tmp[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user