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); |         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); |         FD_ZERO(&sockSet_r); FD_ZERO(&sockSet_w); | ||||||
|         for (it = _socketBaseList.begin(); it != _socketBaseList.end(); it++) { |         for (it = _socketBaseList.begin(); it != _socketBaseList.end(); it++) { | ||||||
|             if ((*it)->_socket != -1) { |             if ((*it)->_socket != -1) { | ||||||
| @@ -123,7 +125,9 @@ void _asynctcpsock_task(void *) | |||||||
|         // Check all sockets to see which ones are active |         // Check all sockets to see which ones are active | ||||||
|         uint32_t nActive = 0; |         uint32_t nActive = 0; | ||||||
|         if (r > 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++) { |             for (it = _socketBaseList.begin(); it != _socketBaseList.end(); it++) { | ||||||
|                 if ((*it)->_selected && FD_ISSET((*it)->_socket, &sockSet_w)) { |                 if ((*it)->_selected && FD_ISSET((*it)->_socket, &sockSet_w)) { | ||||||
|                     sockList.push_back(*it); |                     sockList.push_back(*it); | ||||||
| @@ -147,7 +151,9 @@ void _asynctcpsock_task(void *) | |||||||
|             } |             } | ||||||
|             sockList.clear(); |             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++) { |             for (it = _socketBaseList.begin(); it != _socketBaseList.end(); it++) { | ||||||
|                 if ((*it)->_selected && FD_ISSET((*it)->_socket, &sockSet_r)) { |                 if ((*it)->_selected && FD_ISSET((*it)->_socket, &sockSet_r)) { | ||||||
|                     sockList.push_back(*it); |                     sockList.push_back(*it); | ||||||
| @@ -294,10 +300,12 @@ AsyncClient::AsyncClient(int sockfd) | |||||||
|  |  | ||||||
| AsyncClient::~AsyncClient() | AsyncClient::~AsyncClient() | ||||||
| { | { | ||||||
|  |     xSemaphoreTakeRecursive(_asyncsock_mutex, (TickType_t)portMAX_DELAY); | ||||||
|     if (_socket != -1) _close(); |     if (_socket != -1) _close(); | ||||||
|     _removeAllCallbacks(); |     _removeAllCallbacks(); | ||||||
|     vSemaphoreDelete(_write_mutex); |     vSemaphoreDelete(_write_mutex); | ||||||
|     _write_mutex = NULL; |     _write_mutex = NULL; | ||||||
|  |     xSemaphoreGiveRecursive(_asyncsock_mutex); | ||||||
| } | } | ||||||
|  |  | ||||||
| void AsyncClient::setRxTimeout(uint32_t timeout){ | void AsyncClient::setRxTimeout(uint32_t timeout){ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user