aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Wischer <twischer@de.adit-jv.com>2020-03-26 09:15:18 +0100
committerDavid Robillard <d@drobilla.net>2020-04-05 13:58:21 +0200
commit411f0e67f495fb436ce13ba12c63d7cf874aabd7 (patch)
treeec5af60525a1d4fb3562f4b1a820742eaf6a6da4
parent6721ea54b752b183c45bac83d705f7de40e74fd1 (diff)
downloadjalv-411f0e67f495fb436ce13ba12c63d7cf874aabd7.tar.gz
jalv-411f0e67f495fb436ce13ba12c63d7cf874aabd7.tar.bz2
jalv-411f0e67f495fb436ce13ba12c63d7cf874aabd7.zip
worker: Do not read response when not yet available
Without this patch the size of the response might be read successfully but the response will not be read. Therefore the while loop would exit and when entering the next time the size will be read again. But this second read of size will actually already read data from the response. Therefore the response will be corrupted and the response buffer cannot sync again. To avoid this issue it will first be checked if there is enough data available in the ring buffer to read the size and response. If not try again later. Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
-rw-r--r--src/worker.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/src/worker.c b/src/worker.c
index 79bb7b7..1144120 100644
--- a/src/worker.c
+++ b/src/worker.c
@@ -125,17 +125,36 @@ void
jalv_worker_emit_responses(JalvWorker* worker, LilvInstance* instance)
{
if (worker->responses) {
- uint32_t read_space = zix_ring_read_space(worker->responses);
- while (read_space) {
+ uint32_t read_space = 0;
+ while (read_space = zix_ring_read_space(worker->responses)) {
uint32_t size = 0;
- zix_ring_read(worker->responses, (char*)&size, sizeof(size));
-
- zix_ring_read(worker->responses, (char*)worker->response, size);
+ if (zix_ring_peek(worker->responses, (char*)&size, sizeof(size)) <= 0) {
+ fprintf(stderr, "error: Response buffer corrupted (req %lu avail %u)\n",
+ sizeof(size), read_space);
+ break;
+ }
+
+ const uint32_t packet_size = sizeof(size) + size;
+ if (read_space < packet_size) {
+ fprintf(stderr, "warning: Try to read bigger response (%u) than data available (%u). Retry later.\n",
+ packet_size, read_space);
+ break;
+ }
+
+ if (zix_ring_skip(worker->responses, sizeof(size)) <= 0) {
+ fprintf(stderr, "error: Response buffer corrupted on skip (req %lu avail %u)\n",
+ sizeof(size), read_space);
+ break;
+ }
+
+ if (zix_ring_read(worker->responses, (char*)worker->response, size) <= 0) {
+ fprintf(stderr, "error: Response buffer corrupted on read response (req %u avail %u)\n",
+ size, zix_ring_read_space(worker->responses));
+ break;
+ }
worker->iface->work_response(
instance->lv2_handle, size, worker->response);
-
- read_space -= sizeof(size) + size;
}
}
}