diff options
| author | Felix Fietkau | 2024-03-29 09:23:28 +0000 |
|---|---|---|
| committer | Felix Fietkau | 2024-03-29 12:59:21 +0000 |
| commit | eb9bcb64185ac155c02cc1a604692c4b00368324 (patch) | |
| tree | 0c9021b730d9a94e51640b781e2fd0c175ebd804 | |
| parent | 12bda4bdb1971385fd787737e8eec5a2eeb0deed (diff) | |
| download | libubox-eb9bcb64185ac155c02cc1a604692c4b00368324.tar.gz | |
ustream: prevent recursive calls to the read callback
Simplifies stacked ustreams and calling poll from the read function.
Reuse an unused leftover struct member in order to not break ABI.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
| -rw-r--r-- | ustream.c | 14 | ||||
| -rw-r--r-- | ustream.h | 3 |
2 files changed, 12 insertions, 5 deletions
@@ -24,6 +24,8 @@ #include "ustream.h" +#define CB_PENDING_READ (1 << 0) + static void ustream_init_buf(struct ustream_buf *buf, int len) { if (!len) @@ -133,7 +135,6 @@ void ustream_init_defaults(struct ustream *s) s->state_change.cb = ustream_state_change_cb; s->write_error = false; s->eof = false; - s->eof_write_done = false; s->read_blocked = 0; s->r.buffers = 0; @@ -301,7 +302,6 @@ char *ustream_reserve(struct ustream *s, int len, int *maxlen) void ustream_fill_read(struct ustream *s, int len) { struct ustream_buf *buf = s->r.data_tail; - int n = len; int maxlen; s->r.data_bytes += len; @@ -321,8 +321,14 @@ void ustream_fill_read(struct ustream *s, int len) buf = buf->next; } while (len); - if (s->notify_read) - s->notify_read(s, n); + if (s->notify_read) { + if (s->pending_cb & CB_PENDING_READ) + return; + + s->pending_cb |= CB_PENDING_READ; + s->notify_read(s, s->r.data_bytes); + s->pending_cb &= ~CB_PENDING_READ; + } } char *ustream_get_read_buf(struct ustream *s, int *buflen) @@ -114,7 +114,8 @@ struct ustream { */ bool string_data; bool write_error; - bool eof, eof_write_done; + bool eof; + uint8_t pending_cb; enum read_blocked_reason read_blocked; }; |