From 411f0e67f495fb436ce13ba12c63d7cf874aabd7 Mon Sep 17 00:00:00 2001 From: Timo Wischer Date: Thu, 26 Mar 2020 09:15:18 +0100 Subject: 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 --- src/worker.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'src') 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; } } } -- cgit v1.2.1