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:
matt123p
2019-09-12 17:56:13 +01:00
committed by Me No Dev
parent f0a1c3d486
commit aea43f98d1
3 changed files with 95 additions and 0 deletions

View File

@ -1197,6 +1197,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size)
{
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size);
if (buffer) {
AsyncWebLockGuard l(_lock);
_buffers.add(buffer);
}
return buffer;
@ -1207,6 +1208,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t
AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size);
if (buffer) {
AsyncWebLockGuard l(_lock);
_buffers.add(buffer);
}
@ -1215,6 +1217,8 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t
void AsyncWebSocket::_cleanBuffers()
{
AsyncWebLockGuard l(_lock);
for(AsyncWebSocketMessageBuffer * c: _buffers){
if(c && c->canDelete()){
_buffers.remove(c);

View File

@ -31,6 +31,8 @@
#endif
#include <ESPAsyncWebServer.h>
#include "AsyncWebSynchronization.h"
#ifdef ESP8266
#include <Hash.h>
#endif
@ -236,6 +238,8 @@ class AsyncWebSocket: public AsyncWebHandler {
uint32_t _cNextId;
AwsEventHandler _eventHandler;
bool _enabled;
AsyncWebLock _lock;
public:
AsyncWebSocket(const String& url);
~AsyncWebSocket();

View 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_