From cacac8f871ace3e93490adad9cc8260a6383b821 Mon Sep 17 00:00:00 2001 From: matt123p Date: Mon, 14 Oct 2019 20:38:04 +0100 Subject: [PATCH] Make sure the closed slot is always freed (#68) * Tidy up and fix some edge cases. * Make sure we always release a closed_slot. --- src/AsyncTCP.cpp | 44 ++++++++++++++++++++++++++++---------------- src/AsyncTCP.h | 2 ++ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/AsyncTCP.cpp b/src/AsyncTCP.cpp index bbeffe5..df1560d 100644 --- a/src/AsyncTCP.cpp +++ b/src/AsyncTCP.cpp @@ -82,8 +82,8 @@ static TaskHandle_t _async_service_task_handle = NULL; SemaphoreHandle_t _slots_lock; const int _number_of_closed_slots = CONFIG_LWIP_MAX_ACTIVE_TCP; -static int _closed_slots[_number_of_closed_slots]; -static int _closed_index = []() { +static uint32_t _closed_slots[_number_of_closed_slots]; +static uint32_t _closed_index = []() { _slots_lock = xSemaphoreCreateBinary(); xSemaphoreGive(_slots_lock); for (int i = 0; i < _number_of_closed_slots; ++ i) { @@ -565,17 +565,7 @@ AsyncClient::AsyncClient(tcp_pcb* pcb) _pcb = pcb; _closed_slot = -1; if(_pcb){ - xSemaphoreTake(_slots_lock, portMAX_DELAY); - int closed_slot_min_index = 0; - for (int i = 0; i < _number_of_closed_slots; ++ i) { - if ((_closed_slot == -1 || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) { - closed_slot_min_index = _closed_slots[i]; - _closed_slot = i; - } - } - _closed_slots[_closed_slot] = 0; - xSemaphoreGive(_slots_lock); - + _allocate_closed_slot(); _rx_last_packet = millis(); tcp_arg(_pcb, this); tcp_recv(_pcb, &_tcp_recv); @@ -589,6 +579,7 @@ AsyncClient::~AsyncClient(){ if(_pcb) { _close(); } + _free_closed_slot(); } /* @@ -714,7 +705,6 @@ bool AsyncClient::connect(const char* host, uint16_t port){ ip_addr_t addr; if(!_start_async_task()){ - Serial.println("failed to start task"); log_e("failed to start task"); return false; } @@ -825,6 +815,29 @@ int8_t AsyncClient::_close(){ return err; } +void AsyncClient::_allocate_closed_slot(){ + xSemaphoreTake(_slots_lock, portMAX_DELAY); + uint32_t closed_slot_min_index = 0; + for (int i = 0; i < _number_of_closed_slots; ++ i) { + if ((_closed_slot == -1 || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) { + closed_slot_min_index = _closed_slots[i]; + _closed_slot = i; + } + } + if (_closed_slot != -1) { + _closed_slots[_closed_slot] = 0; + } + xSemaphoreGive(_slots_lock); +} + +void AsyncClient::_free_closed_slot(){ + if (_closed_slot != -1) { + _closed_slots[_closed_slot] = _closed_index; + _closed_slot = -1; + ++ _closed_index; + } +} + /* * Private Callbacks * */ @@ -879,8 +892,7 @@ int8_t AsyncClient::_lwip_fin(tcp_pcb* pcb, int8_t err) { if(tcp_close(_pcb) != ERR_OK) { tcp_abort(_pcb); } - _closed_slots[_closed_slot] = _closed_index; - ++ _closed_index; + _free_closed_slot(); _pcb = NULL; return ERR_OK; } diff --git a/src/AsyncTCP.h b/src/AsyncTCP.h index fef890b..ac87ded 100644 --- a/src/AsyncTCP.h +++ b/src/AsyncTCP.h @@ -170,6 +170,8 @@ class AsyncClient { uint16_t _connect_port; int8_t _close(); + void _free_closed_slot(); + void _allocate_closed_slot(); int8_t _connected(void* pcb, int8_t err); void _error(int8_t err); int8_t _poll(tcp_pcb* pcb);