From e42e8319500672802107bc5e6f09d770ef2d4dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vio=20J=2E=20Saraiva?= Date: Sun, 24 Mar 2024 10:12:27 +0000 Subject: [PATCH] Fix data race in netio_rxl_add and netio_rxl_remove. netio_rxl_cond is signaled when netio_rxl_add_list and netio_rxl_remove_list are empty. netio_rxl_add adds to netio_rxl_add_list and waits for netio_rxl_cond. netio_rxl_remove adds to netio_rxl_remove_list and waits for netio_rxl_cond. The OS can wake up any thread any time, making pthread_cond_wait return too early. Therefore netio_rxl_add could return before the listener was added, and netio_rxl_remove could return before the listener was removed. --- common/net_io.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/common/net_io.c b/common/net_io.c index d919b6c3b..2b0bce52b 100644 --- a/common/net_io.c +++ b/common/net_io.c @@ -1703,8 +1703,9 @@ int netio_rxl_add(netio_desc_t *nio,netio_rx_handler_t rx_handler, rxl->next = netio_rxl_add_list; netio_rxl_add_list = rxl; - - pthread_cond_wait(&netio_rxl_cond,&netio_rxq_mutex); + while(netio_rxl_add_list != NULL) { + pthread_cond_wait(&netio_rxl_cond,&netio_rxq_mutex); + } NETIO_RXQ_UNLOCK(); return(0); } @@ -1715,7 +1716,9 @@ int netio_rxl_remove(netio_desc_t *nio) NETIO_RXQ_LOCK(); nio->rxl_next = netio_rxl_remove_list; netio_rxl_remove_list = nio; - pthread_cond_wait(&netio_rxl_cond,&netio_rxq_mutex); + while(netio_rxl_remove_list != NULL) { + pthread_cond_wait(&netio_rxl_cond,&netio_rxq_mutex); + } NETIO_RXQ_UNLOCK(); return(0); }