From 5da1cd4a38903646f34b4615c5ae3fa046f7da1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 1 Sep 2022 18:47:39 +0200 Subject: [PATCH] module/script: process *all* transactions received in a single read() When the script module received multiple transactions in a single batch, only the first were processed. This lead to multiple, unprocessed transactions stacking up in the receive buffer. Every time a new transaction was received, we popped the oldest transaction from the buffer, but never actually getting to the last one. This is perceived as "lag" by the user, where the bar displays outdated information. Closes #221 --- CHANGELOG.md | 4 +++- modules/script.c | 28 +++++++++++++++------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edaa31e..cafee73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,13 +106,15 @@ * Crash when a particle is “too wide”, and tries to render outside the bar ([#198][198]). * string: crash when failing to convert string to UTF-32. - +* script: only first transaction processed when receiving multiple + transactions in a single batch ([#221][221]). [169]: https://codeberg.org/dnkl/yambar/issues/169 [172]: https://codeberg.org/dnkl/yambar/issues/172 [178]: https://codeberg.org/dnkl/yambar/issues/178 [177]: https://codeberg.org/dnkl/yambar/issues/177 [198]: https://codeberg.org/dnkl/yambar/issues/198 +[221]: https://codeberg.org/dnkl/yambar/issues/221 ### Security diff --git a/modules/script.c b/modules/script.c index 829932f..fd149d2 100644 --- a/modules/script.c +++ b/modules/script.c @@ -313,21 +313,23 @@ data_received(struct module *mod, const char *data, size_t len) memcpy(&m->recv_buf.data[m->recv_buf.idx], data, len); m->recv_buf.idx += len; - const char *eot = memmem(m->recv_buf.data, m->recv_buf.idx, "\n\n", 2); - if (eot == NULL) { - /* End of transaction not yet available */ - return true; + while (true) { + const char *eot = memmem(m->recv_buf.data, m->recv_buf.idx, "\n\n", 2); + if (eot == NULL) { + /* End of transaction not yet available */ + return true; + } + + const size_t transaction_size = eot - m->recv_buf.data + 1; + process_transaction(mod, transaction_size); + + assert(m->recv_buf.idx >= transaction_size + 1); + memmove(m->recv_buf.data, + &m->recv_buf.data[transaction_size + 1], + m->recv_buf.idx - (transaction_size + 1)); + m->recv_buf.idx -= transaction_size + 1; } - const size_t transaction_size = eot - m->recv_buf.data + 1; - process_transaction(mod, transaction_size); - - assert(m->recv_buf.idx >= transaction_size + 1); - memmove(m->recv_buf.data, - &m->recv_buf.data[transaction_size + 1], - m->recv_buf.idx - (transaction_size + 1)); - m->recv_buf.idx -= transaction_size + 1; - return true; }