Skip to content

Commit 7828031

Browse files
committed
Use guard class for LwIP lock
Use a recursion-safe guard class for managing the LwIP lock. This will allow some improvements to reduce code duplication.
1 parent bd3a332 commit 7828031

File tree

1 file changed

+55
-42
lines changed

1 file changed

+55
-42
lines changed

src/AsyncTCP.cpp

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern "C" {
1111
#include "lwip/inet.h"
1212
#include "lwip/opt.h"
1313
#include "lwip/tcp.h"
14+
#include "lwip/tcpip.h"
1415
}
1516

1617
#if CONFIG_ASYNC_TCP_USE_WDT
@@ -24,20 +25,30 @@ extern "C" {
2425
#endif
2526

2627
// https://github.com/espressif/arduino-esp32/issues/10526
28+
namespace {
2729
#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING
28-
#define TCP_MUTEX_LOCK() \
29-
if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \
30-
LOCK_TCPIP_CORE(); \
30+
struct tcp_core_guard {
31+
bool do_lock;
32+
inline tcp_core_guard() : do_lock(!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) {
33+
if (do_lock) {
34+
LOCK_TCPIP_CORE();
35+
}
3136
}
32-
33-
#define TCP_MUTEX_UNLOCK() \
34-
if (sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \
35-
UNLOCK_TCPIP_CORE(); \
37+
inline ~tcp_core_guard() {
38+
if (do_lock) {
39+
UNLOCK_TCPIP_CORE();
40+
}
3641
}
37-
#else // CONFIG_LWIP_TCPIP_CORE_LOCKING
38-
#define TCP_MUTEX_LOCK()
39-
#define TCP_MUTEX_UNLOCK()
42+
tcp_core_guard(const tcp_core_guard &) = delete;
43+
tcp_core_guard(tcp_core_guard &&) = delete;
44+
tcp_core_guard &operator=(const tcp_core_guard &) = delete;
45+
tcp_core_guard &operator=(tcp_core_guard &&) = delete;
46+
} __attribute__((unused));
47+
#else // CONFIG_LWIP_TCPIP_CORE_LOCKING
48+
struct tcp_core_guard {
49+
} __attribute__((unused));
4050
#endif // CONFIG_LWIP_TCPIP_CORE_LOCKING
51+
} // anonymous namespace
4152

4253
#define INVALID_CLOSED_SLOT -1
4354

@@ -811,19 +822,20 @@ bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) {
811822
return false;
812823
}
813824

814-
TCP_MUTEX_LOCK();
815-
tcp_pcb *pcb = tcp_new_ip_type(addr.type);
816-
if (!pcb) {
817-
TCP_MUTEX_UNLOCK();
818-
log_e("pcb == NULL");
819-
return false;
825+
tcp_pcb *pcb;
826+
{
827+
tcp_core_guard tcg;
828+
pcb = tcp_new_ip_type(addr.type);
829+
if (!pcb) {
830+
log_e("pcb == NULL");
831+
return false;
832+
}
833+
tcp_arg(pcb, this);
834+
tcp_err(pcb, &_tcp_error);
835+
tcp_recv(pcb, &_tcp_recv);
836+
tcp_sent(pcb, &_tcp_sent);
837+
tcp_poll(pcb, &_tcp_poll, CONFIG_ASYNC_TCP_POLL_TIMER);
820838
}
821-
tcp_arg(pcb, this);
822-
tcp_err(pcb, &_tcp_error);
823-
tcp_recv(pcb, &_tcp_recv);
824-
tcp_sent(pcb, &_tcp_sent);
825-
tcp_poll(pcb, &_tcp_poll, CONFIG_ASYNC_TCP_POLL_TIMER);
826-
TCP_MUTEX_UNLOCK();
827839

828840
esp_err_t err = _tcp_connect(pcb, _closed_slot, &addr, port, (tcp_connected_fn)&_tcp_connected);
829841
return err == ESP_OK;
@@ -858,9 +870,12 @@ bool AsyncClient::connect(const char *host, uint16_t port) {
858870
return false;
859871
}
860872

861-
TCP_MUTEX_LOCK();
862-
err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
863-
TCP_MUTEX_UNLOCK();
873+
err_t err;
874+
{
875+
tcp_core_guard tcg;
876+
err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
877+
}
878+
864879
if (err == ERR_OK) {
865880
#if ESP_IDF_VERSION_MAJOR < 5
866881
#if LWIP_IPV6
@@ -958,13 +973,14 @@ int8_t AsyncClient::_close() {
958973
// ets_printf("X: 0x%08x\n", (uint32_t)this);
959974
int8_t err = ERR_OK;
960975
if (_pcb) {
961-
TCP_MUTEX_LOCK();
962-
tcp_arg(_pcb, NULL);
963-
tcp_sent(_pcb, NULL);
964-
tcp_recv(_pcb, NULL);
965-
tcp_err(_pcb, NULL);
966-
tcp_poll(_pcb, NULL, 0);
967-
TCP_MUTEX_UNLOCK();
976+
{
977+
tcp_core_guard tcg;
978+
tcp_arg(_pcb, NULL);
979+
tcp_sent(_pcb, NULL);
980+
tcp_recv(_pcb, NULL);
981+
tcp_err(_pcb, NULL);
982+
tcp_poll(_pcb, NULL, 0);
983+
}
968984
_tcp_clear_events(this);
969985
err = _tcp_close(_pcb, _closed_slot);
970986
if (err != ERR_OK) {
@@ -1526,9 +1542,10 @@ void AsyncServer::begin() {
15261542
return;
15271543
}
15281544
int8_t err;
1529-
TCP_MUTEX_LOCK();
1530-
_pcb = tcp_new_ip_type(_bind4 && _bind6 ? IPADDR_TYPE_ANY : (_bind6 ? IPADDR_TYPE_V6 : IPADDR_TYPE_V4));
1531-
TCP_MUTEX_UNLOCK();
1545+
{
1546+
tcp_core_guard tcg;
1547+
_pcb = tcp_new_ip_type(_bind4 && _bind6 ? IPADDR_TYPE_ANY : (_bind6 ? IPADDR_TYPE_V6 : IPADDR_TYPE_V4));
1548+
}
15321549
if (!_pcb) {
15331550
log_e("_pcb == NULL");
15341551
return;
@@ -1561,22 +1578,18 @@ void AsyncServer::begin() {
15611578
log_e("listen_pcb == NULL");
15621579
return;
15631580
}
1564-
TCP_MUTEX_LOCK();
1581+
tcp_core_guard tcg;
15651582
tcp_arg(_pcb, (void *)this);
15661583
tcp_accept(_pcb, &_s_accept);
1567-
TCP_MUTEX_UNLOCK();
15681584
}
15691585

15701586
void AsyncServer::end() {
15711587
if (_pcb) {
1572-
TCP_MUTEX_LOCK();
1588+
tcp_core_guard tcg;
15731589
tcp_arg(_pcb, NULL);
15741590
tcp_accept(_pcb, NULL);
15751591
if (tcp_close(_pcb) != ERR_OK) {
1576-
TCP_MUTEX_UNLOCK();
1577-
_tcp_abort(_pcb, -1);
1578-
} else {
1579-
TCP_MUTEX_UNLOCK();
1592+
tcp_abort(_pcb);
15801593
}
15811594
_pcb = NULL;
15821595
}

0 commit comments

Comments
 (0)