Diff of /src/pkgexec.cpp [2facf8] .. [b70b9b]  Maximize  Restore

Switch to side-by-side view

--- a/src/pkgexec.cpp
+++ b/src/pkgexec.cpp
@@ -4,7 +4,7 @@
  * $Id$
  *
  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2009, 2010, 2011, 2012, MinGW Project
+ * Copyright (C) 2009, 2010, 2011, 2012, 2013, MinGW.org Project
  *
  *
  * Implementation of package management task scheduler and executive.
@@ -31,8 +31,44 @@
 #include "pkgkeys.h"
 #include "pkginfo.h"
 #include "pkgtask.h"
+#include "pkgstat.h"
 #include "pkgopts.h"
 #include "pkgproc.h"
+
+/* The following static member of the pkgSpinWait class provides
+ * the access hook through which the static core implementation of
+ * the base class methods may pass reports back to any derivative
+ * class object, while retaining the capability to issue reports
+ * even when no such object exists.
+ */
+pkgSpinWait *pkgSpinWait::referrer = NULL;
+
+int pkgSpinWait::Report( const char *fmt, ... )
+{
+  /* Also declared as static, this directs printf() style reports
+   * to any existing derivative class object, while behaving as a
+   * no-op in the absence of any such object.
+   */
+  int count = 0;
+  if( referrer != NULL )
+  {
+    va_list argv;
+    va_start( argv, fmt );
+    count = referrer->DispatchReport( fmt, argv );
+    va_end( argv );
+  }
+  return count;
+}
+
+int pkgSpinWait::Indicator( void )
+{
+  /* Once again, declared as static, this method provides a
+   * mechanism for spin-wait animation of any "%c" formatted
+   * field within a progress reporting message.
+   */
+  static const char *marker = "|/-\\";
+  return marker[ referrer->UpdateIndex() ];
+}
 
 EXTERN_C const char *action_name( unsigned long index )
 {
@@ -266,8 +302,58 @@
      * action, in case it is required to complete the request.
      */
     action |= ACTION_DOWNLOAD;
-  rtn->flags = action | (rtn->flags & ~ACTION_MASK);
+  rtn->flags = action | (item.flags & ~ACTION_MASK);
+
+  /* The min_wanted and max_wanted properties, if defined, refer
+   * to dynamically allocated memory blocks, (on the heap); these
+   * must have only one action item owner; currently, the original
+   * item and the copy we've just made are both effective owners,
+   * and we want only the copy to retain this ownership, we must
+   * detach them from the original item.
+   */
+  item.min_wanted = item.max_wanted = NULL;
+
+  /* Similarly, we must transfer any linkage into the schedule of
+   * actions from the original item to the copy.
+   */
+  if( item.prev != NULL ) (item.prev)->next = rtn;
+  if( item.next != NULL ) (item.next)->prev = rtn;
+  item.prev = item.next = NULL;
+
+  /* Finally, we return the copy, leaving the ultimate disposal
+   * of the original to the caller's discretion.
+   */
   return rtn;
+}
+
+void pkgActionItem::Assert
+( unsigned long set, unsigned long mask, pkgActionItem *schedule )
+{
+  /* A method to manipulate the control, error trapping, and state
+   * flags for all items in the specified schedule of actions.
+   *
+   * Starting at the specified item, or the invoking class object
+   * item if no starting point is specified...
+   */
+  if( (schedule != NULL) || ((schedule = this) != NULL) )
+  {
+    /* ...and provided this starting point is not NULL, walk back
+     * to the first item in the associated task schedule...
+     */
+    while( schedule->prev != NULL ) schedule = schedule->prev;
+    while( schedule != NULL )
+    {
+      /* ...then, processing each scheduled task item in sequence,
+       * update the flags according to the specified mask and new
+       * bits to be set...
+       */
+      schedule->flags = (schedule->flags & mask) | set;
+      /*
+       * ...before moving on to the next item in the sequence.
+       */
+      schedule = schedule->next;
+    }
+  }
 }
 
 pkgActionItem*
@@ -429,11 +515,10 @@
     );
 }
 
-void pkgActionItem::Execute()
+void pkgActionItem::Execute( bool with_download )
 {
   if( this != NULL )
-  {
-    pkgActionItem *current = this;
+  { pkgActionItem *current = this;
     bool init_rites_pending = true;
     while( current->prev != NULL ) current = current->prev;
 
@@ -447,7 +532,8 @@
 	    * be necessary to fetch all required archives into
 	    * the local package cache.
 	    */
-	   DownloadArchiveFiles( current );
+	   if( with_download )
+	     DownloadArchiveFiles( current );
 	 } while( SetAuthorities( current ) > 0 );
 
     else while( current != NULL )
@@ -569,10 +655,57 @@
 	}
 	/* Proceed to the next package, if any, with scheduled actions.
 	 */
+	pkgSpinWait::Report( "Processing... (%c)", pkgSpinWait::Indicator() );
 	current = current->next;
       }
     }
   }
+}
+
+pkgActionItem *pkgActionItem::Clear( pkgActionItem *schedule, unsigned long mask )
+{
+  /* Method to remove those action items which have no attribute flags in common
+   * with the specified mask, from the schedule; return the residual schedule of
+   * items, if any, which were not removed.  (Note that specifying a mask with a
+   * value of 0UL, which is the default, results in removal of all items).
+   */
+  pkgActionItem *residual = NULL;
+
+  /* Starting at the specified item, or the invoking class object item
+   * if no starting point is specified...
+   */
+  if( (schedule != NULL) || ((schedule = this) != NULL) )
+  {
+    /* ...and provided this starting point is not NULL, walk back to
+     * the first item in the associated task schedule...
+     */
+    while( schedule->prev != NULL ) schedule = schedule->prev;
+    while( schedule != NULL )
+    {
+      /* ...then, processing each scheduled task item in sequence, and
+       * keeping track of the next to be processed...
+       */
+      pkgActionItem *nextptr = schedule->next;
+      if( (schedule->flags & mask) == 0 )
+	/*
+	 * ...delete each which doesn't match any masked attribute...
+	 */
+	delete schedule;
+
+      else
+        /* ...otherwise add it to the residual schedule.
+	 */
+	residual = schedule;
+
+      /* In either event, move on to the next item in sequence, if any.
+       */
+      schedule = nextptr;
+    }
+  }
+  /* Ultimately, return a pointer to the last item added to the residual
+   * schedule, or NULL if all items were deleted.
+   */
+  return residual;
 }
 
 pkgActionItem::~pkgActionItem()
@@ -597,6 +730,13 @@
      * the same memory referenced by "max_wanted".
      */
     free( (void *)(min_wanted) );
+
+  /* Also ensure that we preserve the integrity of any linked list of
+   * action items in which this item participates, by detaching this
+   * item from the pointer chain.
+   */
+  if( prev != NULL ) prev->next = next;
+  if( next != NULL ) next->prev = prev;
 }
 
 /*

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks