Skip to content

Commit

Permalink
introduce write lock for USB channel
Browse files Browse the repository at this point in the history
  • Loading branch information
andreas committed Nov 24, 2024
1 parent 874dcff commit 8cb012e
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
1 change: 1 addition & 0 deletions lib/channel/GwChannelList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ void GwChannelList::begin(bool fallbackSerial){
if (! fallbackSerial){
GwSerial *usbSerial=createSerialImpl(config, logger,USB_CHANNEL_ID,GWUSB_RX,GWUSB_TX,true);
if (usbSerial != nullptr){
usbSerial->enableWriteLock(); //as it is used for logging we need this additionally
GwChannel *usbChannel=createChannel(logger,config,USB_CHANNEL_ID,usbSerial,GWSERIAL_TYPE_BI);
if (usbChannel != nullptr){
addChannel(usbChannel);
Expand Down
18 changes: 15 additions & 3 deletions lib/queue/GwSynchronized.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,26 @@

class GwSynchronized{
private:
SemaphoreHandle_t *locker;
SemaphoreHandle_t locker=nullptr;
void lock(){
if (locker != nullptr) xSemaphoreTake(locker, portMAX_DELAY);
}
public:
/**
* deprecated
* as SemaphoreHandle_t is already a pointer just use this directly
*/
GwSynchronized(SemaphoreHandle_t *locker){
if (locker == nullptr) return;
this->locker=*locker;
lock();
}
GwSynchronized(SemaphoreHandle_t locker){
this->locker=locker;
if (locker != nullptr) xSemaphoreTake(*locker, portMAX_DELAY);
lock();
}
~GwSynchronized(){
if (locker != nullptr) xSemaphoreGive(*locker);
if (locker != nullptr) xSemaphoreGive(locker);
}
};

Expand Down
13 changes: 9 additions & 4 deletions lib/serial/GwSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ GwSerial::~GwSerial()
{
delete buffer;
if (readBuffer) delete readBuffer;
if (lock != nullptr) vSemaphoreDelete(lock);
}

String GwSerial::getMode(){
Expand All @@ -87,10 +88,14 @@ size_t GwSerial::enqueue(const uint8_t *data, size_t len, bool partial)
}
GwBuffer::WriteStatus GwSerial::write(){
if (! isInitialized()) return GwBuffer::ERROR;
size_t numWrite=availableForWrite();
size_t rt=buffer->fetchData(numWrite,[](uint8_t *buffer,size_t len, void *p){
return ((GwSerial *)p)->stream->write(buffer,len);
},this);
size_t rt=0;
{
GWSYNCHRONIZED(lock);
size_t numWrite=availableForWrite();
rt=buffer->fetchData(numWrite,[](uint8_t *buffer,size_t len, void *p){
return ((GwSerial *)p)->stream->write(buffer,len);
},this);
}
if (rt != 0){
LOG_DEBUG(GwLog::DEBUG+1,"Serial %d write %d",id,rt);
}
Expand Down
5 changes: 5 additions & 0 deletions lib/serial/GwSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "GwLog.h"
#include "GwBuffer.h"
#include "GwChannelInterface.h"
#include "GwSynchronized.h"
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
#include "hal/usb_serial_jtag_ll.h"
#endif
Expand All @@ -26,8 +27,12 @@ class GwSerial : public GwChannelInterface{
virtual long getFlushTimeout(){return 2000;}
virtual int availableForWrite()=0;
int type=0;
SemaphoreHandle_t lock=nullptr;
public:
GwSerial(GwLog *logger,Stream *stream,int id,int type,bool allowRead=true);
void enableWriteLock(){
lock=xSemaphoreCreateMutex();
}
virtual ~GwSerial();
bool isInitialized();
virtual size_t sendToClients(const char *buf,int sourceId,bool partial=false);
Expand Down

0 comments on commit 8cb012e

Please sign in to comment.