From d73eba4a24290c79b40bf5d50957dbcb00e24686 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Tue, 25 Mar 2008 06:06:49 +0200 Subject: [PATCH] Refactor package queue handling into generic queue functions Based on a patch by Ian Jackson . --- ChangeLog | 19 ++++++++++++++++ src/main.h | 17 ++++++++++++++- src/packages.c | 59 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index c5ab8e74..9c1325db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2008-03-25 Ian Jackson , + Guillem Jover + + * src/packages.c (struct pkginqueue): Move declaration to ... + * src/main.h: ... here. + (queuelen): Remove extern declaration. + (struct pkgqueue): New declaration. + (PKGQUEUE_DEF_INIT): New macro. + (add_to_some_queue): New function prototype. + (remove_from_some_queue): Likewise. + * src/packages.c (queuehead, queuetail, queuelen): Replace with ... + (queue): ... this. New variable. Fix all users. + (add_to_queue): Refactor into ... + (add_to_some_queue): ... this. Take a struct pkgqueue argument. + (process_queue): Assert that the queue is empty at the end of the + function. Refactor queue entry removal into ... + (remove_from_some_queue): ... this. New function. + (add_to_queue): New function. + 2008-03-25 Guillem Jover * src/main.h (ensure_package_clientdata): Move prototype to ... diff --git a/src/main.h b/src/main.h index 101ce2e4..63348850 100644 --- a/src/main.h +++ b/src/main.h @@ -49,6 +49,11 @@ struct packageinlist { void *xinfo; }; +struct pkginqueue { + struct pkginqueue *next; + struct pkginfo *pkg; +}; + enum action { act_unset, act_install, act_unpack, act_avail, act_configure, act_remove, act_purge, act_listpackages, act_avreplace, act_avmerge, act_unpackchk, act_status, act_searchfiles, act_audit, act_listfiles, @@ -157,7 +162,17 @@ int breakses_ok(struct pkginfo *pkg, struct varbuf *aemsgs); void deferred_remove(struct pkginfo *pkg); void deferred_configure(struct pkginfo *pkg); -extern int queuelen, sincenothing, dependtry; +extern int sincenothing, dependtry; + +struct pkgqueue { + struct pkginqueue *head, **tail; + int length; +}; + +#define PKGQUEUE_DEF_INIT(name) struct pkgqueue name = { NULL, &name.head, 0 } + +struct pkginqueue *add_to_some_queue(struct pkginfo *pkg, struct pkgqueue *q); +struct pkginqueue *remove_from_some_queue(struct pkgqueue *q); /* from cleanup.c (most of these are declared in archives.h) */ diff --git a/src/packages.c b/src/packages.c index 00321fa1..50f18ec7 100644 --- a/src/packages.c +++ b/src/packages.c @@ -40,25 +40,47 @@ #include "filesdb.h" #include "main.h" -struct pkginqueue { - struct pkginqueue *next; - struct pkginfo *pkg; -}; - -static struct pkginqueue *queuehead = NULL, **queuetail = &queuehead; +static PKGQUEUE_DEF_INIT(queue); -int queuelen=0, sincenothing=0, dependtry=0; +int sincenothing = 0, dependtry = 0; -void add_to_queue(struct pkginfo *pkg) { +struct pkginqueue * +add_to_some_queue(struct pkginfo *pkg, struct pkgqueue *q) +{ struct pkginqueue *newent; newent= m_malloc(sizeof(struct pkginqueue)); newent->pkg= pkg; newent->next = NULL; - *queuetail= newent; - queuetail= &newent->next; + *q->tail = newent; + q->tail = &newent->next; + q->length++; - queuelen++; + return newent; +} + +struct pkginqueue * +remove_from_some_queue(struct pkgqueue *q) +{ + struct pkginqueue *removeent = q->head; + + if (!removeent) + return NULL; + + assert(q->length > 0); + + q->head = q->head->next; + if (q->tail == &removeent->next) + q->tail= &q->head; + q->length--; + + return removeent; +} + +void +add_to_queue(struct pkginfo *pkg) +{ + add_to_some_queue(pkg, &queue); } void packages(const char *const *argv) { @@ -141,10 +163,10 @@ void process_queue(void) { case act_remove: case act_purge: istobe= itb_remove; break; default: internerr("unknown action for queue start"); } - for (rundown= queuehead; rundown; rundown= rundown->next) { + for (rundown = queue.head; rundown; rundown = rundown->next) { ensure_package_clientdata(rundown->pkg); if (rundown->pkg->clientdata->istobe == istobe) { - /* Remove it from the queue - this is a second copy ! */ + /* Erase the queue entrie - this is a second copy ! */ switch (cipaction->arg) { case act_configure: case act_remove: case act_purge: printf(_("Package %s listed more than once, only processing once.\n"), @@ -164,13 +186,7 @@ void process_queue(void) { } } - while (queuelen) { - removeent= queuehead; - assert(removeent); - queuehead= queuehead->next; - queuelen--; - if (queuetail == &removeent->next) queuetail= &queuehead; - + while ((removeent = remove_from_some_queue(&queue))) { pkg= removeent->pkg; free(removeent); @@ -186,7 +202,7 @@ void process_queue(void) { continue; } push_error_handler(&ejbuf,print_error_perpackage,pkg->name); - if (sincenothing++ > queuelen*2+2) { + if (sincenothing++ > queue.length * 2 + 2) { dependtry++; sincenothing= 0; assert(dependtry <= 4); } @@ -209,6 +225,7 @@ void process_queue(void) { set_error_display(NULL, NULL); error_unwind(ehflag_normaltidy); } + assert(!queue.length); } /*** dependency processing - common to --configure and --remove ***/ -- 2.39.5