Catch tcpip_callback call failure

tcpip_callback_with_block() can fail with ERR_MEM or ERR_VAL, and in the
error paths the code does not post the msg to the mailbox thus the
sys_sem_wait() call might wait forever. Fix it by testing return value of
tcpip_callback() and return error immediately.

Signed-off-by: Axel Lin <axel.lin@ingics.com>
This commit is contained in:
Axel Lin 2015-12-01 18:59:04 +08:00 committed by Dirk Ziegelmeier
parent a21144b834
commit a3bccae173
2 changed files with 20 additions and 3 deletions

View File

@ -868,7 +868,14 @@ netconn_gethostbyname(const char *name, ip_addr_t *addr)
}
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg));
err = tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg));
if (err != ERR_OK) {
#if !LWIP_NETCONN_SEM_PER_THREAD
sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem));
#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
API_VAR_FREE(MEMP_DNS_API_MSG, msg);
return err;
}
sys_sem_wait(API_EXPR_REF_SEM(API_VAR_REF(msg).sem));
#if !LWIP_NETCONN_SEM_PER_THREAD
sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem));

View File

@ -1820,7 +1820,12 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
#else
LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed;
#endif
tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data));
err = tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data));
if (err != ERR_OK) {
LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
sock_set_errno(sock, err_to_errno(err));
return -1;
}
sys_arch_sem_wait((sys_sem_t*)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0);
/* write back optlen and optval */
@ -2224,7 +2229,12 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
#else
LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed;
#endif
tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data));
err = tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data));
if (err != ERR_OK) {
LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data);
sock_set_errno(sock, err_to_errno(err));
return -1;
}
sys_arch_sem_wait((sys_sem_t*)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0);
/* maybe lwip_getsockopt_internal has changed err */