xbps_archive_fetch_xxx: avoid races with multiple threads in the libfetch code.

Protect our critical sections with a mutex for now, until libfetch
is really fixed to work correctly with multiple threads.
This commit is contained in:
Juan RP 2014-12-22 18:18:20 +01:00
parent 8593f21848
commit 6a985190aa
2 changed files with 19 additions and 2 deletions

4
NEWS
View File

@ -1,5 +1,9 @@
xbps-0.43 (???): xbps-0.43 (???):
* libxbps: xbps_archive_fetch_xxx() are now protected with a mutex to avoid
data races with 8 threads or more. Reproducable by @chneukirchen on a
8 core machine.
xbps-0.42 (2014-12-22): xbps-0.42 (2014-12-22):
* xbps-reconfigure(8): new option -i, --ignore to ignore packages * xbps-reconfigure(8): new option -i, --ignore to ignore packages

View File

@ -30,6 +30,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
@ -43,6 +44,7 @@ struct fetch_archive {
struct url *url; struct url *url;
struct fetchIO *fetch; struct fetchIO *fetch;
char buffer[32768]; char buffer[32768];
pthread_mutex_t mtx;
}; };
static int static int
@ -50,7 +52,10 @@ fetch_archive_open(struct archive *a _unused, void *client_data)
{ {
struct fetch_archive *f = client_data; struct fetch_archive *f = client_data;
pthread_mutex_lock(&f->mtx);
f->fetch = fetchGet(f->url, NULL); f->fetch = fetchGet(f->url, NULL);
pthread_mutex_unlock(&f->mtx);
if (f->fetch == NULL) if (f->fetch == NULL)
return ENOENT; return ENOENT;
@ -61,10 +66,13 @@ static ssize_t
fetch_archive_read(struct archive *a _unused, void *client_data, const void **buf) fetch_archive_read(struct archive *a _unused, void *client_data, const void **buf)
{ {
struct fetch_archive *f = client_data; struct fetch_archive *f = client_data;
ssize_t res;
*buf = f->buffer; *buf = f->buffer;
pthread_mutex_lock(&f->mtx);
return fetchIO_read(f->fetch, f->buffer, sizeof(f->buffer)); res = fetchIO_read(f->fetch, f->buffer, sizeof(f->buffer));
pthread_mutex_unlock(&f->mtx);
return res;
} }
static int static int
@ -72,8 +80,11 @@ fetch_archive_close(struct archive *a _unused, void *client_data)
{ {
struct fetch_archive *f = client_data; struct fetch_archive *f = client_data;
pthread_mutex_lock(&f->mtx);
if (f->fetch != NULL) if (f->fetch != NULL)
fetchIO_close(f->fetch); fetchIO_close(f->fetch);
pthread_mutex_unlock(&f->mtx);
pthread_mutex_destroy(&f->mtx);
free(f); free(f);
return 0; return 0;
@ -90,6 +101,8 @@ open_archive_by_url(struct url *url)
return NULL; return NULL;
f->url = url; f->url = url;
pthread_mutex_init(&f->mtx, NULL);
if ((a = archive_read_new()) == NULL) { if ((a = archive_read_new()) == NULL) {
free(f); free(f);
return NULL; return NULL;