Skip to content
This repository was archived by the owner on Mar 5, 2026. It is now read-only.

Commit aea43f9

Browse files
matt123pme-no-dev
authored andcommitted
Add thread locking to improve stability. (me-no-dev#585)
* Add thread locking to improve stability. * Do not use thread locking with the ESP8266, but instead use an empty placeholder class that can be used to implement locking at a later date.
1 parent f0a1c3d commit aea43f9

3 files changed

Lines changed: 95 additions & 0 deletions

File tree

src/AsyncWebSocket.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size)
11971197
{
11981198
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size);
11991199
if (buffer) {
1200+
AsyncWebLockGuard l(_lock);
12001201
_buffers.add(buffer);
12011202
}
12021203
return buffer;
@@ -1207,6 +1208,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t
12071208
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size);
12081209

12091210
if (buffer) {
1211+
AsyncWebLockGuard l(_lock);
12101212
_buffers.add(buffer);
12111213
}
12121214

@@ -1215,6 +1217,8 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t
12151217

12161218
void AsyncWebSocket::_cleanBuffers()
12171219
{
1220+
AsyncWebLockGuard l(_lock);
1221+
12181222
for(AsyncWebSocketMessageBuffer * c: _buffers){
12191223
if(c && c->canDelete()){
12201224
_buffers.remove(c);

src/AsyncWebSocket.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#endif
3232
#include <ESPAsyncWebServer.h>
3333

34+
#include "AsyncWebSynchronization.h"
35+
3436
#ifdef ESP8266
3537
#include <Hash.h>
3638
#endif
@@ -236,6 +238,8 @@ class AsyncWebSocket: public AsyncWebHandler {
236238
uint32_t _cNextId;
237239
AwsEventHandler _eventHandler;
238240
bool _enabled;
241+
AsyncWebLock _lock;
242+
239243
public:
240244
AsyncWebSocket(const String& url);
241245
~AsyncWebSocket();

src/AsyncWebSynchronization.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#ifndef ASYNCWEBSYNCHRONIZATION_H_
2+
#define ASYNCWEBSYNCHRONIZATION_H_
3+
4+
// Synchronisation is only available on ESP32, as the ESP8266 isn't using FreeRTOS by default
5+
6+
#include <ESPAsyncWebServer.h>
7+
8+
#ifdef ESP32
9+
10+
// This is the ESP32 version of the Sync Lock, using the FreeRTOS Semaphore
11+
class AsyncWebLock
12+
{
13+
private:
14+
SemaphoreHandle_t _lock;
15+
mutable void *_lockedBy;
16+
17+
public:
18+
AsyncWebLock() {
19+
_lock = xSemaphoreCreateBinary();
20+
_lockedBy = NULL;
21+
xSemaphoreGive(_lock);
22+
}
23+
24+
~AsyncWebLock() {
25+
vSemaphoreDelete(_lock);
26+
}
27+
28+
bool lock() const {
29+
extern void *pxCurrentTCB;
30+
if (_lockedBy != pxCurrentTCB) {
31+
xSemaphoreTake(_lock, portMAX_DELAY);
32+
_lockedBy = pxCurrentTCB;
33+
return true;
34+
}
35+
return false;
36+
}
37+
38+
void unlock() const {
39+
_lockedBy = NULL;
40+
xSemaphoreGive(_lock);
41+
}
42+
};
43+
44+
#else
45+
46+
// This is the 8266 version of the Sync Lock which is currently unimplemented
47+
class AsyncWebLock
48+
{
49+
50+
public:
51+
AsyncWebLock() {
52+
}
53+
54+
~AsyncWebLock() {
55+
}
56+
57+
bool lock() const {
58+
return false;
59+
}
60+
61+
void unlock() const {
62+
}
63+
};
64+
#endif
65+
66+
class AsyncWebLockGuard
67+
{
68+
private:
69+
const AsyncWebLock *_lock;
70+
71+
public:
72+
AsyncWebLockGuard(const AsyncWebLock &l) {
73+
if (l.lock()) {
74+
_lock = &l;
75+
} else {
76+
_lock = NULL;
77+
}
78+
}
79+
80+
~AsyncWebLockGuard() {
81+
if (_lock) {
82+
_lock->unlock();
83+
}
84+
}
85+
};
86+
87+
#endif // ASYNCWEBSYNCHRONIZATION_H_

0 commit comments

Comments
 (0)