From: Dongwoo Lee Date: Thu, 19 Dec 2024 06:23:47 +0000 (+0900) Subject: net: Make check_next_chunk() mutually exclusive X-Git-Tag: accepted/tools/devbase/tools/legacy/20250527.042524~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d8510092c75a5b534705275a38e208bc102615a6;p=tools%2Flthor.git net: Make check_next_chunk() mutually exclusive Since 4004285311 ("Fix the race in data_finished() and resp_finished()"), Although the possibility of a race between two threads executing data_finished() and resp_finished() is reduced, it is still possible to enter the check_next_chunk() function at the same time in certain circumstances as below: Thread A | Thread B -------------------------------------------------+-------------------------------------------------------------- | chunk->resp_finished = 1; chunk->data_finished = 1; | if (chunk->resp_finished) | check_next_chunk(chunk, transfer); | chunk->chunk_number = transfer->chunk_number++; | | if (chunk->data_finished) | check_next_chunk(chunk, transfer); | >> chunk->chunk_number = transfer->chunk_number++; | chunk->data_finished = chunk->resp_finished = 0; | … To address this, this makes the functions completely mutually exclusive. Change-Id: I94df217ec82dadc322050693e86763f9c8213d05 Signed-off-by: Dongwoo Lee --- diff --git a/libthor/thor_net.c b/libthor/thor_net.c index 9da314c..55a6306 100644 --- a/libthor/thor_net.c +++ b/libthor/thor_net.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "thor.h" #include "thor_internal.h" @@ -149,6 +150,7 @@ struct t_thor_net_chunk { int chunk_number; int data_finished; int resp_finished; + pthread_mutex_t lock; }; struct t_thor_net_transfer { @@ -258,9 +260,14 @@ static void data_finished(sigval_t sigval) return; } + pthread_mutex_lock(&chunk->lock); chunk->data_finished = 1; - if (chunk->resp_finished) + pthread_mutex_unlock(&chunk->lock); + + pthread_mutex_lock(&chunk->lock); + if (chunk->data_finished && chunk->resp_finished) check_next_chunk(chunk, transfer); + pthread_mutex_unlock(&chunk->lock); } static void resp_finished(sigval_t sigval) @@ -307,9 +314,14 @@ static void resp_finished(sigval_t sigval) chunk->chunk_number, transfer->user_data); + pthread_mutex_lock(&chunk->lock); chunk->resp_finished = 1; - if (chunk->data_finished) + pthread_mutex_unlock(&chunk->lock); + + pthread_mutex_lock(&chunk->lock); + if (chunk->data_finished && chunk->resp_finished) check_next_chunk(chunk, transfer); + pthread_mutex_unlock(&chunk->lock); } static int thor_net_send_raw_data(thor_device_handle *th, @@ -348,6 +360,8 @@ static int thor_net_send_raw_data(thor_device_handle *th, if (!chunk.buf) return -ENOMEM; + pthread_mutex_init(&chunk.lock, NULL); + chunk.data_transfer.aio_fildes = nh->sock_fd; chunk.data_transfer.aio_buf = chunk.buf; chunk.data_transfer.aio_nbytes = chunk.trans_unit_size;