mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-30 03:26:13 +01:00
protect ringstream
This commit is contained in:
parent
d7e46ac625
commit
55c7a0a1e8
|
@ -30,28 +30,36 @@ RingStream::RingStream( const uint16_t len)
|
||||||
_overflow=false;
|
_overflow=false;
|
||||||
_mark=0;
|
_mark=0;
|
||||||
_count=0;
|
_count=0;
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
portMUX_TYPE _bufMux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RingStream::write(uint8_t b) {
|
size_t RingStream::write(uint8_t b) {
|
||||||
if (_overflow) return 0;
|
if (_overflow) return 0;
|
||||||
|
portENTER_CRITICAL(&_bufMux);
|
||||||
_buffer[_pos_write] = b;
|
_buffer[_pos_write] = b;
|
||||||
++_pos_write;
|
++_pos_write;
|
||||||
if (_pos_write==_len) _pos_write=0;
|
if (_pos_write==_len) _pos_write=0;
|
||||||
if (_pos_write==_pos_read) {
|
if (_pos_write==_pos_read) {
|
||||||
_overflow=true;
|
_overflow=true;
|
||||||
|
portEXIT_CRITICAL(&_bufMux);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_count++;
|
_count++;
|
||||||
|
portEXIT_CRITICAL(&_bufMux);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RingStream::read(byte advance) {
|
int RingStream::read(byte advance) {
|
||||||
if ((_pos_read==_pos_write) && !_overflow) return -1; // empty
|
if ((_pos_read==_pos_write) && !_overflow) return -1; // empty
|
||||||
if (_pos_read == _mark) return -1;
|
if (_pos_read == _mark) return -1;
|
||||||
|
portENTER_CRITICAL(&_bufMux);
|
||||||
byte b=_buffer[_pos_read];
|
byte b=_buffer[_pos_read];
|
||||||
_pos_read += advance;
|
_pos_read += advance;
|
||||||
if (_pos_read==_len) _pos_read=0;
|
if (_pos_read==_len) _pos_read=0;
|
||||||
_overflow=false;
|
_overflow=false;
|
||||||
|
portEXIT_CRITICAL(&_bufMux);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,11 +78,13 @@ int RingStream::freeSpace() {
|
||||||
// mark start of message with client id (0...9)
|
// mark start of message with client id (0...9)
|
||||||
void RingStream::mark(uint8_t b) {
|
void RingStream::mark(uint8_t b) {
|
||||||
//DIAG(F("Mark1 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
|
//DIAG(F("Mark1 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
|
||||||
|
portENTER_CRITICAL(&_bufMux);
|
||||||
_mark=_pos_write;
|
_mark=_pos_write;
|
||||||
write(b); // client id
|
write(b); // client id
|
||||||
write((uint8_t)0); // count MSB placemarker
|
write((uint8_t)0); // count MSB placemarker
|
||||||
write((uint8_t)0); // count LSB placemarker
|
write((uint8_t)0); // count LSB placemarker
|
||||||
_count=0;
|
_count=0;
|
||||||
|
portEXIT_CRITICAL(&_bufMux);
|
||||||
}
|
}
|
||||||
|
|
||||||
// peekTargetMark is used by the parser stash routines to know which client
|
// peekTargetMark is used by the parser stash routines to know which client
|
||||||
|
@ -89,16 +99,19 @@ void RingStream::info() {
|
||||||
|
|
||||||
bool RingStream::commit() {
|
bool RingStream::commit() {
|
||||||
//DIAG(F("Commit1 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
|
//DIAG(F("Commit1 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
|
||||||
|
portENTER_CRITICAL(&_bufMux);
|
||||||
if (_overflow) {
|
if (_overflow) {
|
||||||
DIAG(F("RingStream(%d) commit(%d) OVERFLOW"),_len, _count);
|
DIAG(F("RingStream(%d) commit(%d) OVERFLOW"),_len, _count);
|
||||||
// just throw it away
|
// just throw it away
|
||||||
_pos_write=_mark;
|
_pos_write=_mark;
|
||||||
_overflow=false;
|
_overflow=false;
|
||||||
|
portEXIT_CRITICAL(&_bufMux);
|
||||||
return false; // commit failed
|
return false; // commit failed
|
||||||
}
|
}
|
||||||
if (_count==0) {
|
if (_count==0) {
|
||||||
// ignore empty response
|
// ignore empty response
|
||||||
_pos_write=_mark;
|
_pos_write=_mark;
|
||||||
|
portEXIT_CRITICAL(&_bufMux);
|
||||||
return true; // true=commit ok
|
return true; // true=commit ok
|
||||||
}
|
}
|
||||||
// Go back to the _mark and inject the count 1 byte later
|
// Go back to the _mark and inject the count 1 byte later
|
||||||
|
@ -110,5 +123,6 @@ bool RingStream::commit() {
|
||||||
_buffer[_mark]=lowByte(_count);
|
_buffer[_mark]=lowByte(_count);
|
||||||
_mark=_len+1;
|
_mark=_len+1;
|
||||||
//DIAG(F("Commit2 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
|
//DIAG(F("Commit2 len=%d count=%d pr=%d pw=%d m=%d"),_len, _count,_pos_read,_pos_write,_mark);
|
||||||
|
portEXIT_CRITICAL(&_bufMux);
|
||||||
return true; // commit worked
|
return true; // commit worked
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,9 @@ class RingStream : public Print {
|
||||||
int _mark;
|
int _mark;
|
||||||
int _count;
|
int _count;
|
||||||
byte * _buffer;
|
byte * _buffer;
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
portMUX_TYPE _bufMux;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user