diff options
author | Timo Wischer <twischer@de.adit-jv.com> | 2020-03-26 09:15:18 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-04-05 13:58:21 +0200 |
commit | 411f0e67f495fb436ce13ba12c63d7cf874aabd7 (patch) | |
tree | ec5af60525a1d4fb3562f4b1a820742eaf6a6da4 /src | |
parent | 6721ea54b752b183c45bac83d705f7de40e74fd1 (diff) | |
download | jalv-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>
Diffstat (limited to 'src')
-rw-r--r-- | src/worker.c | 33 |
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; } } } |