forked from me-no-dev/ESPAsyncWebServer
Add thread locking to improve stability. (#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.
This commit is contained in:
@ -1197,6 +1197,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size)
|
|||||||
{
|
{
|
||||||
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size);
|
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size);
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
|
AsyncWebLockGuard l(_lock);
|
||||||
_buffers.add(buffer);
|
_buffers.add(buffer);
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -1207,6 +1208,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t
|
|||||||
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size);
|
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size);
|
||||||
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
|
AsyncWebLockGuard l(_lock);
|
||||||
_buffers.add(buffer);
|
_buffers.add(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1215,6 +1217,8 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t
|
|||||||
|
|
||||||
void AsyncWebSocket::_cleanBuffers()
|
void AsyncWebSocket::_cleanBuffers()
|
||||||
{
|
{
|
||||||
|
AsyncWebLockGuard l(_lock);
|
||||||
|
|
||||||
for(AsyncWebSocketMessageBuffer * c: _buffers){
|
for(AsyncWebSocketMessageBuffer * c: _buffers){
|
||||||
if(c && c->canDelete()){
|
if(c && c->canDelete()){
|
||||||
_buffers.remove(c);
|
_buffers.remove(c);
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
#include "AsyncWebSynchronization.h"
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#include <Hash.h>
|
#include <Hash.h>
|
||||||
#endif
|
#endif
|
||||||
@ -236,6 +238,8 @@ class AsyncWebSocket: public AsyncWebHandler {
|
|||||||
uint32_t _cNextId;
|
uint32_t _cNextId;
|
||||||
AwsEventHandler _eventHandler;
|
AwsEventHandler _eventHandler;
|
||||||
bool _enabled;
|
bool _enabled;
|
||||||
|
AsyncWebLock _lock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AsyncWebSocket(const String& url);
|
AsyncWebSocket(const String& url);
|
||||||
~AsyncWebSocket();
|
~AsyncWebSocket();
|
||||||
|
87
src/AsyncWebSynchronization.h
Normal file
87
src/AsyncWebSynchronization.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#ifndef ASYNCWEBSYNCHRONIZATION_H_
|
||||||
|
#define ASYNCWEBSYNCHRONIZATION_H_
|
||||||
|
|
||||||
|
// Synchronisation is only available on ESP32, as the ESP8266 isn't using FreeRTOS by default
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
// This is the ESP32 version of the Sync Lock, using the FreeRTOS Semaphore
|
||||||
|
class AsyncWebLock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SemaphoreHandle_t _lock;
|
||||||
|
mutable void *_lockedBy;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AsyncWebLock() {
|
||||||
|
_lock = xSemaphoreCreateBinary();
|
||||||
|
_lockedBy = NULL;
|
||||||
|
xSemaphoreGive(_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
~AsyncWebLock() {
|
||||||
|
vSemaphoreDelete(_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lock() const {
|
||||||
|
extern void *pxCurrentTCB;
|
||||||
|
if (_lockedBy != pxCurrentTCB) {
|
||||||
|
xSemaphoreTake(_lock, portMAX_DELAY);
|
||||||
|
_lockedBy = pxCurrentTCB;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock() const {
|
||||||
|
_lockedBy = NULL;
|
||||||
|
xSemaphoreGive(_lock);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// This is the 8266 version of the Sync Lock which is currently unimplemented
|
||||||
|
class AsyncWebLock
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
AsyncWebLock() {
|
||||||
|
}
|
||||||
|
|
||||||
|
~AsyncWebLock() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lock() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock() const {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class AsyncWebLockGuard
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const AsyncWebLock *_lock;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AsyncWebLockGuard(const AsyncWebLock &l) {
|
||||||
|
if (l.lock()) {
|
||||||
|
_lock = &l;
|
||||||
|
} else {
|
||||||
|
_lock = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~AsyncWebLockGuard() {
|
||||||
|
if (_lock) {
|
||||||
|
_lock->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ASYNCWEBSYNCHRONIZATION_H_
|
Reference in New Issue
Block a user