mirror of
				https://github.com/eledio-devices/thirdparty-AsyncTCPSock.git
				synced 2025-10-31 00:32:37 +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