From c44c159065daf8bc7ab6c03287f281d317b1d5fd Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Tue, 15 Oct 2019 02:48:32 +0000 Subject: [PATCH] network: fix data race when accessing sending_sockets This can happen with more than 1 WriteThreads --- src/network.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/network.c b/src/network.c index 8acf84b1..a1a6e3d0 100644 --- a/src/network.c +++ b/src/network.c @@ -142,6 +142,7 @@ typedef struct sockent { } data; struct sockent *next; + pthread_mutex_t lock; } sockent_t; /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 @@ -1540,6 +1541,7 @@ static void sockent_destroy(sockent_t *se) /* {{{ */ sfree(se->node); sfree(se->service); + pthread_mutex_destroy(&se->lock); if (se->type == SOCKENT_TYPE_CLIENT) free_sockent_client(&se->data.client); @@ -1858,6 +1860,7 @@ static sockent_t *sockent_create(int type) /* {{{ */ se->service = NULL; se->interface = 0; se->next = NULL; + pthread_mutex_init(&se->lock, NULL); if (type == SOCKENT_TYPE_SERVER) { se->data.server.fd = NULL; @@ -1949,6 +1952,8 @@ static int sockent_client_disconnect(sockent_t *se) /* {{{ */ client->fd = -1; } + DEBUG("network plugin: free (se = %p, addr = %p);", (void *)se, + (void *)client->addr); sfree(client->addr); client->addrlen = 0; @@ -2020,6 +2025,8 @@ static int sockent_client_connect(sockent_t *se) /* {{{ */ client->fd = -1; continue; } + DEBUG("network plugin: alloc (se = %p, addr = %p);", (void *)se, + (void *)client->addr); assert(sizeof(*client->addr) >= ai_ptr->ai_addrlen); memcpy(client->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen); @@ -2541,6 +2548,7 @@ static void network_send_buffer(char *buffer, size_t buffer_len) /* {{{ */ buffer_len); for (sockent_t *se = sending_sockets; se != NULL; se = se->next) { + pthread_mutex_lock(&se->lock); #if HAVE_GCRYPT_H if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT) network_send_buffer_encrypted(se, buffer, buffer_len); @@ -2549,6 +2557,7 @@ static void network_send_buffer(char *buffer, size_t buffer_len) /* {{{ */ else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */ #endif /* HAVE_GCRYPT_H */ network_send_buffer_plain(se, buffer, buffer_len); + pthread_mutex_unlock(&se->lock); } /* for (sending_sockets) */ } /* }}} void network_send_buffer */ -- 2.11.0