]> err.no Git - dpkg/commitdiff
Refactor package queue handling into generic queue functions
authorGuillem Jover <guillem@debian.org>
Tue, 25 Mar 2008 04:06:49 +0000 (06:06 +0200)
committerGuillem Jover <guillem@debian.org>
Tue, 25 Mar 2008 04:06:49 +0000 (06:06 +0200)
Based on a patch by Ian Jackson <ian@davenant.greenend.org.uk>.

ChangeLog
src/main.h
src/packages.c

index c5ab8e7419fedf6b2f810ea0df160a4915cbf48a..9c1325db8ffaa9d479f559de69aafd4aaeaae10e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2008-03-25  Ian Jackson  <ian@davenant.greenend.org.uk>,
+            Guillem Jover  <guillem@debian.org>
+
+       * 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  <guillem@debian.org>
 
        * src/main.h (ensure_package_clientdata): Move prototype to ...
index 101ce2e4e22e571c1d8c60965f02f9acdf547fa1..63348850808ddf4ce76fda8e7599f6369273e2f9 100644 (file)
@@ -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) */
 
index 00321fa16c69e35cfa6e82934d0790ca96a9d9a6..50f18ec702ddc060fe140aeeadd192267e16dfb4 100644 (file)
 #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 ***/