summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2014-09-29 00:15:10 +0200
committerAndrew Gregory <andrew.gregory.8@gmail.com>2017-05-11 06:45:30 +0200
commita391c54eb3df2d8de32c6ce4d5e2b05c46dbf487 (patch)
treedcf88956bf727e6e061d26d65da73eba72a4ebf4
parent20bc9067c16c790172fbccb28043e1148040a5c1 (diff)
downloadpacman-a391c54eb3df2d8de32c6ce4d5e2b05c46dbf487.tar.gz
pacman-a391c54eb3df2d8de32c6ce4d5e2b05c46dbf487.tar.xz
use multiple threads for signature checking
-rw-r--r--lib/libalpm/sync.c105
-rw-r--r--lib/libalpm/thread.h4
2 files changed, 80 insertions, 29 deletions
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index c1579753..0e537696 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -47,6 +47,7 @@
#include "remove.h"
#include "diskspace.h"
#include "signing.h"
+#include "thread.h"
/** Check for new version of pkg in sync repos
* (only the first occurrence is considered in sync)
@@ -57,11 +58,7 @@ alpm_pkg_t SYMEXPORT *alpm_sync_newversion(alpm_pkg_t *pkg, alpm_list_t *dbs_syn
alpm_pkg_t *spkg = NULL;
ASSERT(pkg != NULL, return NULL);
-<<<<<<< HEAD
- pkg->handle->pm_errno = ALPM_ERR_OK;
-=======
_alpm_set_errno(pkg->handle, ALPM_ERR_OK);
->>>>>>> make pm_errno thread-local
for(i = dbs_sync; !spkg && i; i = i->next) {
alpm_db_t *db = i->data;
@@ -1121,37 +1118,60 @@ static int check_keyring(alpm_handle_t *handle)
}
#endif /* HAVE_LIBGPGME */
-static int check_validity(alpm_handle_t *handle,
- size_t total, uint64_t total_bytes)
+struct validity {
+ alpm_pkg_t *pkg;
+ char *path;
+ alpm_siglist_t *siglist;
+ alpm_siglevel_t level;
+ alpm_pkgvalidation_t validation;
+ alpm_errno_t error;
+};
+
+struct validity_payload {
+ alpm_handle_t *handle;
+ alpm_list_t *pkgs;
+ alpm_list_t *errors;
+ size_t current;
+ size_t total;
+};
+
+static alpm_list_t *_alpm_list_shift(alpm_list_t **list)
{
- struct validity {
- alpm_pkg_t *pkg;
- char *path;
- alpm_siglist_t *siglist;
- int siglevel;
- int validation;
- alpm_errno_t error;
- };
- size_t current = 0;
- uint64_t current_bytes = 0;
- alpm_list_t *i, *errors = NULL;
- alpm_event_t event;
-
- /* Check integrity of packages */
- event.type = ALPM_EVENT_INTEGRITY_START;
- EVENT(handle, &event);
+ if(*list) {
+ alpm_list_t *ret = *list;
+ *list = ret->next;
+ return ret;
+ } else {
+ return NULL;
+ }
+}
- for(i = handle->trans->add; i; i = i->next, current++) {
+static void *check_validity_single(void *payload)
+{
+ struct validity_payload *args = payload;
+ alpm_handle_t *handle = args->handle;
+ alpm_list_t *pkgs = args->pkgs;
+
+ while(1) {
+ alpm_list_t *i;
+
+ _ALPM_TLOCK_TASK(handle);
+ i = _alpm_list_shift(&pkgs);
+ if(!i) {
+ _ALPM_TUNLOCK_TASK(handle);
+ return NULL;
+ }
struct validity v = { i->data, NULL, NULL, 0, 0, 0 };
- int percent = (int)(((double)current_bytes / total_bytes) * 100);
+ args->current++;
+ _ALPM_TUNLOCK_TASK(handle);
+
+ PROGRESS(handle, ALPM_PROGRESS_INTEGRITY_START, "",
+ 100 * (args->current) / (args->total), (args->total), (args->current));
- PROGRESS(handle, ALPM_PROGRESS_INTEGRITY_START, "", percent,
- total, current);
if(v.pkg->origin == ALPM_PKG_FROM_FILE) {
continue; /* pkg_load() has been already called, this package is valid */
}
- current_bytes += v.pkg->size;
v.path = _alpm_filecache_find(handle, v.pkg->filename);
v.siglevel = alpm_db_get_siglevel(alpm_pkg_get_db(v.pkg));
@@ -1159,9 +1179,11 @@ static int check_validity(alpm_handle_t *handle,
v.siglevel, &v.siglist, &v.validation) == -1) {
struct validity *invalid;
v.error = alpm_errno(handle);
- MALLOC(invalid, sizeof(struct validity), return -1);
+ MALLOC(invalid, sizeof(struct validity), return NULL);
memcpy(invalid, &v, sizeof(struct validity));
- errors = alpm_list_add(errors, invalid);
+ _ALPM_TLOCK_TASK(handle);
+ args->errors = alpm_list_add(args->errors, invalid);
+ _ALPM_TUNLOCK_TASK(handle);
} else {
alpm_siglist_cleanup(v.siglist);
free(v.siglist);
@@ -1169,6 +1191,31 @@ static int check_validity(alpm_handle_t *handle,
v.pkg->validation = v.validation;
}
}
+ return NULL;
+}
+
+static int check_validity(alpm_handle_t *handle,
+ size_t total, uint64_t UNUSED total_bytes)
+{
+ size_t current = 0;
+ alpm_list_t *i, *errors = NULL;
+ alpm_event_t event;
+ struct validity_payload args = {
+ handle,
+ handle->trans->add,
+ errors,
+ current,
+ total,
+ };
+
+ /* Check integrity of packages */
+ event.type = ALPM_EVENT_INTEGRITY_START;
+ EVENT(handle, &event);
+
+ PROGRESS(handle, ALPM_PROGRESS_INTEGRITY_START, "", 0,
+ total, current);
+
+ _alpm_run_threaded(handle, check_validity_single, &args);
PROGRESS(handle, ALPM_PROGRESS_INTEGRITY_START, "", 100,
total, current);
diff --git a/lib/libalpm/thread.h b/lib/libalpm/thread.h
index 1773bdae..305b63f6 100644
--- a/lib/libalpm/thread.h
+++ b/lib/libalpm/thread.h
@@ -24,17 +24,21 @@
#define _ALPM_TLOCK_CB(h) pthread_mutex_lock(&((h)->tlock_cb))
#define _ALPM_TLOCK_LOG(h) pthread_mutex_lock(&((h)->tlock_log))
+#define _ALPM_TLOCK_TASK(h) pthread_mutex_lock(&((h)->tlock_task))
#define _ALPM_TUNLOCK_CB(h) pthread_mutex_unlock(&((h)->tlock_cb))
#define _ALPM_TUNLOCK_LOG(h) pthread_mutex_unlock(&((h)->tlock_log))
+#define _ALPM_TUNLOCK_TASK(h) pthread_mutex_unlock(&((h)->tlock_task))
#else
#define _ALPM_TLOCK_CB(h)
#define _ALPM_TLOCK_LOG(h)
+#define _ALPM_TLOCK_TASK(h)
#define _ALPM_TUNLOCK_CB(h)
#define _ALPM_TUNLOCK_LOG(h)
+#define _ALPM_TUNLOCK_TASK(h)
#endif /* HAVE_PTHREAD */