mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
syslog: stop the log ring from lapping its reader
write_char() masked writeptr and never looked at readptr, so once more than LOGBUF_SIZE bytes were written between two drains the ring wrapped over content that had not been sent yet. That is not a corner case. The ring is emptied once per main loop pass, while a single command runs to completion inside one pass, and a full L2 listing prints well over twice the 512 byte buffer. On hardware the whole 1227 byte dump came out as one 174 byte datagram whose first line began in the middle of a MAC address. Drop the character when the ring is full instead of overwriting, so what has been logged stays intact and it is the tail that is lost. A full ring also flags a line, otherwise a burst without a newline would leave the reader waiting on line_available forever and syslog would stop for good.
This commit is contained in:
1 parent
6488433584
commit
552bd1cb18
1 file changed
+13
-2
+13
-2
@@ -277,8 +277,19 @@ void write_char(char c)
|
|||||||
write_char_no_syslog(c);
|
write_char_no_syslog(c);
|
||||||
|
|
||||||
if (syslog_state.enabled) {
|
if (syslog_state.enabled) {
|
||||||
logbuf[syslog_state.writeptr++] = c;
|
__xdata uint16_t next = (syslog_state.writeptr + 1) & (LOGBUF_SIZE - 1);
|
||||||
syslog_state.writeptr &= (LOGBUF_SIZE - 1);
|
|
||||||
|
/* The ring is drained once per main loop pass, and a single command
|
||||||
|
* can print several times its size, so writing on regardless laps
|
||||||
|
* the reader and the datagram starts mid record. Drop instead, and
|
||||||
|
* flag a line so the reader empties what is there even if no
|
||||||
|
* newline has been seen yet. */
|
||||||
|
if (next == syslog_state.readptr) {
|
||||||
|
syslog_state.line_available = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logbuf[syslog_state.writeptr] = c;
|
||||||
|
syslog_state.writeptr = next;
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
syslog_state.line_available = 1;
|
syslog_state.line_available = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user