Skip to content

Commit 5b43fe3

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 124a8e0 commit 5b43fe3

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
@@ -29,6 +29,7 @@ extern "C" {
2929
#include "lwip/inet.h"
3030
#include "lwip/opt.h"
3131
#include "lwip/tcp.h"
32+
#include "lwip/tcpip.h"
3233
}
3334

3435
#if CONFIG_ASYNC_TCP_USE_WDT
@@ -39,20 +40,30 @@ extern "C" {
3940
// https://github.com/espressif/arduino-esp32/blob/3.0.3/libraries/Network/src/NetworkInterface.cpp#L37-L47
4041

4142
// https://github.com/espressif/arduino-esp32/issues/10526
43+
namespace {
4244
#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING
43-
#define TCP_MUTEX_LOCK() \
44-
if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \
45-
LOCK_TCPIP_CORE(); \
45+
struct tcp_core_guard {
46+
bool do_lock;
47+
inline tcp_core_guard() : do_lock(!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) {
48+
if (do_lock) {
49+
LOCK_TCPIP_CORE();
50+
}
4651
}
47-
48-
#define TCP_MUTEX_UNLOCK() \
49-
if (sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \
50-
UNLOCK_TCPIP_CORE(); \
52+
inline ~tcp_core_guard() {
53+
if (do_lock) {
54+
UNLOCK_TCPIP_CORE();
55+
}
5156
}
52-
#else // CONFIG_LWIP_TCPIP_CORE_LOCKING
53-
#define TCP_MUTEX_LOCK()
54-
#define TCP_MUTEX_UNLOCK()
57+
tcp_core_guard(const tcp_core_guard &) = delete;
58+
tcp_core_guard(tcp_core_guard &&) = delete;
59+
tcp_core_guard &operator=(const tcp_core_guard &) = delete;
60+
tcp_core_guard &operator=(tcp_core_guard &&) = delete;
61+
} __attribute__((unused));
62+
#else // CONFIG_LWIP_TCPIP_CORE_LOCKING
63+
struct tcp_core_guard {
64+
} __attribute__((unused));
5565
#endif // CONFIG_LWIP_TCPIP_CORE_LOCKING
66+
} // anonymous namespace
5667

5768
#define INVALID_CLOSED_SLOT -1
5869

@@ -826,19 +837,20 @@ bool AsyncClient::connect(ip_addr_t addr, uint16_t port) {
826837
return false;
827838
}
828839

829-
TCP_MUTEX_LOCK();
830-
tcp_pcb *pcb = tcp_new_ip_type(addr.type);
831-
if (!pcb) {
832-
TCP_MUTEX_UNLOCK();
833-
log_e("pcb == NULL");
834-
return false;
840+
tcp_pcb *pcb;
841+
{
842+
tcp_core_guard tcg;
843+
pcb = tcp_new_ip_type(addr.type);
844+
if (!pcb) {
845+
log_e("pcb == NULL");
846+
return false;
847+
}
848+
tcp_arg(pcb, this);
849+
tcp_err(pcb, &_tcp_error);
850+
tcp_recv(pcb, &_tcp_recv);
851+
tcp_sent(pcb, &_tcp_sent);
852+
tcp_poll(pcb, &_tcp_poll, CONFIG_ASYNC_TCP_POLL_TIMER);
835853
}
836-
tcp_arg(pcb, this);
837-
tcp_err(pcb, &_tcp_error);
838-
tcp_recv(pcb, &_tcp_recv);
839-
tcp_sent(pcb, &_tcp_sent);
840-
tcp_poll(pcb, &_tcp_poll, CONFIG_ASYNC_TCP_POLL_TIMER);
841-
TCP_MUTEX_UNLOCK();
842854

843855
esp_err_t err = _tcp_connect(pcb, _closed_slot, &addr, port, (tcp_connected_fn)&_tcp_connected);
844856
return err == ESP_OK;
@@ -875,9 +887,12 @@ bool AsyncClient::connect(const char *host, uint16_t port) {
875887
return false;
876888
}
877889

878-
TCP_MUTEX_LOCK();
879-
err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
880-
TCP_MUTEX_UNLOCK();
890+
err_t err;
891+
{
892+
tcp_core_guard tcg;
893+
err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
894+
}
895+
881896
if (err == ERR_OK) {
882897
#if ESP_IDF_VERSION_MAJOR < 5
883898
#if LWIP_IPV6
@@ -975,13 +990,14 @@ int8_t AsyncClient::_close() {
975990
// ets_printf("X: 0x%08x\n", (uint32_t)this);
976991
int8_t err = ERR_OK;
977992
if (_pcb) {
978-
TCP_MUTEX_LOCK();
979-
tcp_arg(_pcb, NULL);
980-
tcp_sent(_pcb, NULL);
981-
tcp_recv(_pcb, NULL);
982-
tcp_err(_pcb, NULL);
983-
tcp_poll(_pcb, NULL, 0);
984-
TCP_MUTEX_UNLOCK();
993+
{
994+
tcp_core_guard tcg;
995+
tcp_arg(_pcb, NULL);
996+
tcp_sent(_pcb, NULL);
997+
tcp_recv(_pcb, NULL);
998+
tcp_err(_pcb, NULL);
999+
tcp_poll(_pcb, NULL, 0);
1000+
}
9851001
_tcp_clear_events(this);
9861002
err = _tcp_close(_pcb, _closed_slot);
9871003
if (err != ERR_OK) {
@@ -1548,9 +1564,10 @@ void AsyncServer::begin() {
15481564
return;
15491565
}
15501566
int8_t err;
1551-
TCP_MUTEX_LOCK();
1552-
_pcb = tcp_new_ip_type(_addr.type);
1553-
TCP_MUTEX_UNLOCK();
1567+
{
1568+
tcp_core_guard tcg;
1569+
_pcb = tcp_new_ip_type(_addr.type);
1570+
}
15541571
if (!_pcb) {
15551572
log_e("_pcb == NULL");
15561573
return;
@@ -1571,22 +1588,18 @@ void AsyncServer::begin() {
15711588
log_e("listen_pcb == NULL");
15721589
return;
15731590
}
1574-
TCP_MUTEX_LOCK();
1591+
tcp_core_guard tcg;
15751592
tcp_arg(_pcb, (void *)this);
15761593
tcp_accept(_pcb, &_s_accept);
1577-
TCP_MUTEX_UNLOCK();
15781594
}
15791595

15801596
void AsyncServer::end() {
15811597
if (_pcb) {
1582-
TCP_MUTEX_LOCK();
1598+
tcp_core_guard tcg;
15831599
tcp_arg(_pcb, NULL);
15841600
tcp_accept(_pcb, NULL);
15851601
if (tcp_close(_pcb) != ERR_OK) {
1586-
TCP_MUTEX_UNLOCK();
1587-
_tcp_abort(_pcb, -1);
1588-
} else {
1589-
TCP_MUTEX_UNLOCK();
1602+
tcp_abort(_pcb);
15901603
}
15911604
_pcb = NULL;
15921605
}

0 commit comments

Comments
 (0)