diff options
author | Mateusz Moscicki <m.moscicki2@partner.samsung.com> | 2022-10-27 19:53:27 +0200 |
---|---|---|
committer | Mateusz Moscicki <m.moscicki2@partner.samsung.com> | 2022-10-28 07:35:36 +0200 |
commit | 400428531184493e9d025af29286d071f84c1115 (patch) | |
tree | b2c4570384ef3eeebaaa736b595323c4ee7bc8a5 | |
parent | d0d2cfbfbefb0a2e4687bc5d07ce30acab796fb0 (diff) | |
download | lthor-400428531184493e9d025af29286d071f84c1115.tar.gz lthor-400428531184493e9d025af29286d071f84c1115.tar.bz2 lthor-400428531184493e9d025af29286d071f84c1115.zip |
Fix the race in data_finished() and resp_finished()
Setting the data_finished and resp_finished flags too early sometimes
led to a situation in which another chunk was sent, even though the
functions had not finished executing, which resulted in a flashing
error.
For example:
When data_finished() was called, the flag data_finished was set. Then
after entering aio_error/aio_return the thread would be put to sleep and
the program would start executing the resp_finished() function. The
function was executed to the end and because data_finished flag was set,
the check_next_chunk() was called.
After that, the thread with data_finished() would return from sleep and
continue its execution, even though the data it was pointing to at that
moment is out of date. This led, among other things, to a mismatch
between numbers of chunk and the response.
Change-Id: I404b3723cb9e671d13221bff2b7823f1fdc43906
Signed-off-by: Mateusz Moscicki <m.moscicki2@samsung.com>
-rw-r--r-- | libthor/thor_net.c | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/libthor/thor_net.c b/libthor/thor_net.c index 29cb295..9da314c 100644 --- a/libthor/thor_net.c +++ b/libthor/thor_net.c @@ -242,8 +242,6 @@ static void data_finished(sigval_t sigval) struct t_thor_net_transfer *transfer = chunk->user_data; int ret; - chunk->data_finished = 1; - ret = aio_error(&chunk->data_transfer); if (ret == ECANCELED || transfer->ret) { return; @@ -260,6 +258,7 @@ static void data_finished(sigval_t sigval) return; } + chunk->data_finished = 1; if (chunk->resp_finished) check_next_chunk(chunk, transfer); } @@ -270,7 +269,6 @@ static void resp_finished(sigval_t sigval) struct t_thor_net_transfer *transfer = chunk->user_data; int ret; - chunk->resp_finished = 1; transfer->data_in_progress -= chunk->useful_size; ret = aio_error(&chunk->resp_transfer); @@ -309,6 +307,7 @@ static void resp_finished(sigval_t sigval) chunk->chunk_number, transfer->user_data); + chunk->resp_finished = 1; if (chunk->data_finished) check_next_chunk(chunk, transfer); } |