mirror of
https://github.com/eledio-devices/thirdparty-AsyncTCPSock.git
synced 2025-10-30 16:15:40 +01:00
Protect against AsyncClient being destroyed in the middle of processing
- Take the _asyncsock_mutex in AsyncClient destructor. This should handle scenarios where a previously-valid client is destroyed by another task while being examined by the asyncTcpSock task. - Since the _asyncsock_mutex is released before being taken again by the AsyncSocketBase destructor, examined objects may be still "half-destroyed" (AsyncClient destructor terminated and _write_mutex invalid, but still waiting for lock in AsyncSocketBase destructor). However, _socket may now be guaranteed to remain valid if it was valid when the _asyncsock_mutex was taken.
This commit is contained in:
@@ -88,7 +88,9 @@ void _asynctcpsock_task(void *)
|
||||
|
||||
xSemaphoreTakeRecursive(_asyncsock_mutex, (TickType_t)portMAX_DELAY);
|
||||
|
||||
// Collect all of the active sockets into socket set
|
||||
// Collect all of the active sockets into socket set. Half-destroyed
|
||||
// connections should have set _socket to -1 and therefore should not
|
||||
// end up in the sockList.
|
||||
FD_ZERO(&sockSet_r); FD_ZERO(&sockSet_w);
|
||||
for (it = _socketBaseList.begin(); it != _socketBaseList.end(); it++) {
|
||||
if ((*it)->_socket != -1) {
|
||||
@@ -123,7 +125,9 @@ void _asynctcpsock_task(void *)
|
||||
// Check all sockets to see which ones are active
|
||||
uint32_t nActive = 0;
|
||||
if (r > 0) {
|
||||
// Collect and notify all writable sockets
|
||||
// Collect and notify all writable sockets. Half-destroyed connections
|
||||
// should have set _socket to -1 and therefore should not end up in
|
||||
// the sockList.
|
||||
for (it = _socketBaseList.begin(); it != _socketBaseList.end(); it++) {
|
||||
if ((*it)->_selected && FD_ISSET((*it)->_socket, &sockSet_w)) {
|
||||
sockList.push_back(*it);
|
||||
@@ -147,7 +151,9 @@ void _asynctcpsock_task(void *)
|
||||
}
|
||||
sockList.clear();
|
||||
|
||||
// Collect and notify all readable sockets
|
||||
// Collect and notify all readable sockets. Half-destroyed connections
|
||||
// should have set _socket to -1 and therefore should not end up in
|
||||
// the sockList.
|
||||
for (it = _socketBaseList.begin(); it != _socketBaseList.end(); it++) {
|
||||
if ((*it)->_selected && FD_ISSET((*it)->_socket, &sockSet_r)) {
|
||||
sockList.push_back(*it);
|
||||
@@ -294,10 +300,12 @@ AsyncClient::AsyncClient(int sockfd)
|
||||
|
||||
AsyncClient::~AsyncClient()
|
||||
{
|
||||
xSemaphoreTakeRecursive(_asyncsock_mutex, (TickType_t)portMAX_DELAY);
|
||||
if (_socket != -1) _close();
|
||||
_removeAllCallbacks();
|
||||
vSemaphoreDelete(_write_mutex);
|
||||
_write_mutex = NULL;
|
||||
xSemaphoreGiveRecursive(_asyncsock_mutex);
|
||||
}
|
||||
|
||||
void AsyncClient::setRxTimeout(uint32_t timeout){
|
||||
|
||||
Reference in New Issue
Block a user