download: remove mutex lock in single thread code

Functions clean_curl_multi_queue() and swupd_curl_hashmap_insert() are
always called in the same thread so there isn't any need to protect
access to swupd_curl_hashbucket or swupd_curl_hashmap.

The download.c functions use curl_multi infrastructure to download in parallel
but all processing is performed in the main thread. So we don't need to worry
about concurrency problems in object access.

But we need to worry about concurrency in file access. Fortunatelly the hashmap
prevents the same file to be downloaded twice, so we are safe on that.
This commit is contained in:
Otavio Pontes
2018-07-13 16:15:41 -07:00
committed by Matthew Johnson
parent 076cd0a73d
commit f80257d6c1
3 changed files with 11 additions and 28 deletions
+1 -2
View File
@@ -63,8 +63,7 @@ swupd_LDADD = \
$(openssl_LIBS) \
$(curl_LIBS) \
$(bsdiff_LIBS) \
$(libarchive_LIBS) \
$(pthread_LIBS)
$(libarchive_LIBS)
verifytime_SOURCES = src/verifytime.c
bin_PROGRAMS += verifytime
-1
View File
@@ -22,7 +22,6 @@ PKG_CHECK_MODULES([zlib], [zlib])
PKG_CHECK_MODULES([curl], [libcurl])
PKG_CHECK_MODULES([openssl], [libcrypto >= 1.0.1])
PKG_CHECK_MODULES([libarchive], [libarchive])
AC_CHECK_LIB([pthread], [pthread_create])
# Program checks
+10 -25
View File
@@ -26,7 +26,6 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -61,12 +60,8 @@ static struct list *failed = NULL;
*
* file->hash[0] acts as index into the arrays
*/
struct swupd_curl_hashbucket {
pthread_mutex_t mutex;
struct list *list;
};
#define SWUPD_CURL_HASH_BUCKETS 256
static struct swupd_curl_hashbucket swupd_curl_hashmap[SWUPD_CURL_HASH_BUCKETS];
static struct list *swupd_curl_hashmap[SWUPD_CURL_HASH_BUCKETS];
/* try to insert the file into the hashmap download queue
* returns 1 if no download is needed
@@ -80,16 +75,15 @@ static int swupd_curl_hashmap_insert(struct file *file)
char *targetfile;
struct stat stat;
int hashmap_index = file->hash[0];
struct swupd_curl_hashbucket *bucket = &swupd_curl_hashmap[hashmap_index];
struct list **bucket;
pthread_mutex_lock(&bucket->mutex);
bucket = &swupd_curl_hashmap[hashmap_index];
iter = bucket->list;
iter = *bucket;
while (iter) {
tmp = iter->data;
if (hash_equal(tmp->hash, file->hash)) {
// hash already in download queue
pthread_mutex_unlock(&bucket->mutex);
return 1;
}
iter = iter->next;
@@ -103,7 +97,6 @@ static int swupd_curl_hashmap_insert(struct file *file)
if (verify_file(file, targetfile)) {
/* hash matches, no download necessary */
free_string(&targetfile);
pthread_mutex_unlock(&bucket->mutex);
return 1;
} else {
/* hash mismatch, remove the staged file to enable re-download */
@@ -121,14 +114,12 @@ static int swupd_curl_hashmap_insert(struct file *file)
free_string(&tar_dotfile);
// queue the hash for download
iter = bucket->list;
iter = *bucket;
if ((iter = list_prepend_data(iter, file)) == NULL) {
pthread_mutex_unlock(&bucket->mutex);
return -1;
}
bucket->list = iter;
*bucket = iter;
pthread_mutex_unlock(&bucket->mutex);
return 0;
}
@@ -138,12 +129,7 @@ static size_t MAX_XFER_BOTTOM = 15;
int start_full_download(bool pipelining)
{
int i;
failed = NULL;
for (i = 0; i < SWUPD_CURL_HASH_BUCKETS; i++) {
pthread_mutex_init(&swupd_curl_hashmap[i].mutex, NULL);
}
mcurl = curl_multi_init();
if (mcurl == NULL) {
@@ -183,14 +169,13 @@ static void free_curl_list_data(void *data)
void clean_curl_multi_queue(void)
{
int i;
struct swupd_curl_hashbucket *bucket;
struct list **bucket;
for (i = 0; i < SWUPD_CURL_HASH_BUCKETS; i++) {
bucket = &swupd_curl_hashmap[i];
pthread_mutex_lock(&bucket->mutex);
list_free_list_and_data(bucket->list, free_curl_list_data);
bucket->list = NULL;
pthread_mutex_unlock(&bucket->mutex);
list_free_list_and_data(*bucket, free_curl_list_data);
*bucket = NULL;
}
}