[Aptitude-svn-commit] r4065 - in branches/aptitude-0.3/aptitude: . src src/generic

Daniel Burrows dburrows at costa.debian.org
Fri Sep 9 21:48:08 UTC 2005


Author: dburrows
Date: Fri Sep  9 21:48:05 2005
New Revision: 4065

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/download_list.cc
   branches/aptitude-0.3/aptitude/src/download_list.h
   branches/aptitude-0.3/aptitude/src/download_manager.cc
   branches/aptitude-0.3/aptitude/src/download_manager.h
   branches/aptitude-0.3/aptitude/src/generic/acqprogress.cc
   branches/aptitude-0.3/aptitude/src/generic/acqprogress.h
Log:
Add basic support for continuation-passing in download status callbacks.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Fri Sep  9 21:48:05 2005
@@ -1,3 +1,11 @@
+2005-09-09  Daniel Burrows  <dburrows at debian.org>
+
+	* src/download_manager.cc, src/download_manager.h, src/download_list.h, src/generic/acqprogress.cc, src/generic/acqprogress.h:
+
+	  Write basic support for continuation-passing in the download
+	  status callbacks; this will allow complete elimination of
+	  vscreen_mainloop calls.
+
 2005-09-07  Daniel Burrows  <dburrows at debian.org>
 
 	* src/generic/aptitude_resolver_universe.h, src/generic/dense_setset.h, src/generic/problemresolver/problemresolver.h:

Modified: branches/aptitude-0.3/aptitude/src/download_list.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/download_list.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/download_list.cc	Fri Sep  9 21:48:05 2005
@@ -273,8 +273,9 @@
   vscreen_exitmain();
 }
 
-bool download_list::MediaChange(string media, string drive,
-				download_manager &manager)
+void download_list::MediaChange(string media, string drive,
+				download_manager &manager,
+				const sigc::slot1<void, bool> &k)
 {
   fragment *f=wrapbox(fragf(_("Please insert the disc labeled \"%s\" into the drive \"%s\""),
 			    media.c_str(), drive.c_str()));
@@ -294,7 +295,7 @@
 
   vscreen_mainloop();
 
-  return rval;
+  k(rval);
 }
 
 void download_list::IMSHit(pkgAcquire::ItemDesc &itmdesc,
@@ -368,7 +369,7 @@
   msgs.erase(msgs.begin(), msgs.end());
 }
 
-void download_list::Stop(download_manager &manager)
+void download_list::Stop(download_manager &manager, const sigc::slot0<void> &k)
 {
   string s=aptcfg->Find(PACKAGE "::UI::Pause-After-Download", "OnlyIfError");
 
@@ -390,6 +391,8 @@
 				    manager.get_currentCPS()));
       vscreen_mainloop();
     }
+
+  k();
 }
 
 void download_list::Complete(download_manager &manager)
@@ -398,7 +401,8 @@
   destroy();
 }
 
-bool download_list::Pulse(pkgAcquire *Owner, download_manager &manager)
+void download_list::Pulse(pkgAcquire *Owner, download_manager &manager,
+			  const sigc::slot1<void, bool> &k)
 {
   TotalBytes=manager.get_total_bytes();
   TotalItems=manager.get_total_items();
@@ -412,9 +416,9 @@
     vscreen_queuelayout(); // Force an update
 
   if(cancelled)
-    return false;
+    k(false);
   else
-    return true;
+    k(true);
 }
 
 int download_list::width_request()

Modified: branches/aptitude-0.3/aptitude/src/download_list.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/download_list.h	(original)
+++ branches/aptitude-0.3/aptitude/src/download_list.h	Fri Sep  9 21:48:05 2005
@@ -95,15 +95,17 @@
     return new download_list(abortslot, display_messages);
   }
 
-  bool MediaChange(std::string media, std::string drive,
-		   download_manager &manager);
+  void MediaChange(std::string media, std::string drive,
+		   download_manager &manager,
+		   const sigc::slot1<void, bool> &k);
   void IMSHit(pkgAcquire::ItemDesc &itmdesc, download_manager &manager);
   void Fetch(pkgAcquire::ItemDesc &itmdesc, download_manager &manager);
   void Done(pkgAcquire::ItemDesc &itmdesc, download_manager &manager);
   void Fail(pkgAcquire::ItemDesc &itmdesc, download_manager &manager);
-  bool Pulse(pkgAcquire *Owner, download_manager &manager);
+  void Pulse(pkgAcquire *Owner, download_manager &manager,
+	     const sigc::slot1<void, bool> &k);
   void Start(download_manager &manager);
-  void Stop(download_manager &manager);
+  void Stop(download_manager &manager, const sigc::slot0<void> &k);
   void Complete(download_manager &manager);
 
   int width_request();

Modified: branches/aptitude-0.3/aptitude/src/download_manager.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/download_manager.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/download_manager.cc	Fri Sep  9 21:48:05 2005
@@ -6,6 +6,8 @@
 
 #include "vscreen/vscreen_widget.h"
 
+#include <sigc++/adaptors/bind.h>
+
 download_manager::download_manager()
 {
 }
@@ -20,6 +22,17 @@
   w = _w;
 }
 
+/** If out is 1, do nothing; otherwise, set out to either 1 or 0,
+ *  depending on whether val is \b true or \b false.
+ */
+static void set_bool(bool val, int *out)
+{
+  if(*out == 1)
+    return;
+
+  *out = val ? 1 : 0;
+}
+
 void download_manager::Fetched(unsigned long Size, unsigned long ResumePoint)
 {
   pkgAcquireStatus::Fetched(Size, ResumePoint);
@@ -27,9 +40,23 @@
   Fetched_sig(Size, ResumePoint, *this);
 }
 
+void download_manager::MediaChange(const string &Media, const string &Drive,
+				   const sigc::slot1<void, bool> &k)
+{
+  MediaChange_sig(Media, Drive, *this, k);
+}
+
 bool download_manager::MediaChange(string Media, string Drive)
 {
-  return MediaChange_sig(Media, Drive, *this);
+  int rval = -1;
+
+  MediaChange(Media, Drive, sigc::bind(sigc::ptr_fun(set_bool), &rval));
+
+  // Sanity-check against broken slots.  Something ought to have
+  // called this.
+  if(!MediaChange_sig.empty())
+    assert(rval != -1);
+  return rval != 0;
 }
 
 void download_manager::IMSHit(pkgAcquire::ItemDesc &item)
@@ -52,11 +79,23 @@
   Fail_sig(item, *this);
 }
 
-bool download_manager::Pulse(pkgAcquire *Owner)
+void download_manager::Pulse(pkgAcquire *Owner,
+			     const sigc::slot1<void, bool> &k)
 {
   pkgAcquireStatus::Pulse(Owner);
 
-  return Pulse_sig(Owner, *this);
+  Pulse_sig(Owner, *this, k);
+}
+
+bool download_manager::Pulse(pkgAcquire *Owner)
+{
+  int rval = -1;
+
+  Pulse(Owner, sigc::bind(sigc::ptr_fun(set_bool), &rval));
+
+  if(!Pulse_sig.empty())
+    assert(rval != -1);
+  return rval != 0;
 }
 
 void download_manager::Start()
@@ -66,11 +105,20 @@
   Start_sig(*this);
 }
 
-void download_manager::Stop()
+void download_manager::Stop(const sigc::slot0<void> &k)
 {
   pkgAcquireStatus::Stop();
 
-  Stop_sig(*this);
+  Stop_sig(*this, k);
+}
+
+static void nop()
+{
+}
+
+void download_manager::Stop()
+{
+  Stop(sigc::ptr_fun(nop));
 }
 
 void download_manager::Complete()

Modified: branches/aptitude-0.3/aptitude/src/download_manager.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/download_manager.h	(original)
+++ branches/aptitude-0.3/aptitude/src/download_manager.h	Fri Sep  9 21:48:05 2005
@@ -18,7 +18,30 @@
 class vscreen_widget;
 typedef ref_ptr<vscreen_widget> vs_widget_ref;
 
-class download_manager:public pkgAcquireStatus
+/** A download manager translates AcquireStatus calls into signals.
+ *  Typically only one slot will be attached to each signal, but this
+ *  allows a degree of separation to be introduced between the
+ *  back-end progress object and the higher-level objects that display
+ *  the current progress.
+ *
+ *  The signals emitted by this class can be divided into groups.
+ *  With most of the signals, the download class will block until the
+ *  signal emission is complete.  However, several signals pass an
+ *  extra slot argument called the "continuation"; this should be
+ *  called (with the "result", if any, of the signal) when the task
+ *  identified by the signal is completed.  The purpose here is to
+ *  allow the non-blocking display of prompts such as the Media Change
+ *  dialog.
+ *
+ *  The signals which take a continuation are currently MediaChange,
+ *  Pulse, and Stop.  They also provide an implementation that is not
+ *  continuation-passing; this version should be used only when no
+ *  cross-thread calls are being performed and the connectee of the
+ *  signals is known to not defer its response (i.e., it calls the
+ *  continuation before returning).  Mainly this means the
+ *  command-line download mode.
+ */
+class download_manager : public pkgAcquireStatus
 {
   // A widget which should live in memory at least as long as this
   // download does.  Used to ensure that widgets which are responsible
@@ -30,8 +53,6 @@
 
   void set_widget(const vs_widget_ref &_w);
 
-  // Private variables?  Bah, I'll give you private variables..
-
   struct timeval &get_time() {return Time;}
   struct timeval &get_start_time() {return StartTime;}
   double get_last_bytes() {return LastBytes;}
@@ -47,25 +68,31 @@
 
   sigc::signal3<void, unsigned long, unsigned long,
 		download_manager &> Fetched_sig;
-  sigc::signal3<bool, std::string, std::string,
-		download_manager &> MediaChange_sig;
+  sigc::signal4<void, std::string, std::string,
+		download_manager &, const sigc::slot1<void, bool> &> MediaChange_sig;
   sigc::signal2<void, pkgAcquire::ItemDesc &, download_manager &> IMSHit_sig;
   sigc::signal2<void, pkgAcquire::ItemDesc &, download_manager &> Fetch_sig;
   sigc::signal2<void, pkgAcquire::ItemDesc &, download_manager &> Done_sig;
   sigc::signal2<void, pkgAcquire::ItemDesc &, download_manager &> Fail_sig;
-  sigc::signal2<bool, pkgAcquire *, download_manager &> Pulse_sig;
+  sigc::signal3<void, pkgAcquire *, download_manager &,
+		const sigc::slot1<void, bool> &> Pulse_sig;
   sigc::signal1<void, download_manager &> Start_sig;
-  sigc::signal1<void, download_manager &> Stop_sig;
+  sigc::signal2<void, download_manager &,
+		const sigc::slot0<void> &> Stop_sig;
   sigc::signal1<void, download_manager &> Complete_sig;
 
   void Fetched(unsigned long Size, unsigned long ResumePoint);
+  void MediaChange(const std::string &Media, const std::string &Drive,
+		   const sigc::slot1<void, bool> &k);
   bool MediaChange(std::string Media, std::string Drive);
   void IMSHit(pkgAcquire::ItemDesc &item);
   void Fetch(pkgAcquire::ItemDesc &item);
   void Done(pkgAcquire::ItemDesc &item);
   void Fail(pkgAcquire::ItemDesc &item);
+  void Pulse(pkgAcquire *Owner, const sigc::slot1<void, bool> &k);
   bool Pulse(pkgAcquire *Owner);
   void Start();
+  void Stop(const sigc::slot0<void> &k);
   void Stop();
 
   // Called when EVERYTHING is over.  "Stop" is not sufficient, since

Modified: branches/aptitude-0.3/aptitude/src/generic/acqprogress.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/acqprogress.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/acqprogress.cc	Fri Sep  9 21:48:05 2005
@@ -130,10 +130,14 @@
 // ---------------------------------------------------------------------
 /* This prints out the bytes downloaded and the overall average line
    speed */
-void AcqTextStatus::Stop(download_manager &manager)
+void AcqTextStatus::Stop(download_manager &manager,
+			 const sigc::slot0<void> &k)
 {
    if (Quiet > 1)
-      return;
+     {
+       k();
+       return;
+     }
 
    if (Quiet <= 0)
       cout << '\r' << BlankLine << '\r' << flush;
@@ -143,6 +147,8 @@
 	       SizeToStr(manager.get_fetched_bytes()).c_str(),
 	       TimeToStr(manager.get_elapsed_time()).c_str(),
 	       SizeToStr(manager.get_currentCPS()).c_str());
+
+   k();
 }
 									/*}}}*/
 // AcqTextStatus::Pulse - Regular event pulse				/*{{{*/
@@ -150,7 +156,8 @@
 /* This draws the current progress. Each line has an overall percent
    meter and a per active item status meter along with an overall 
    bandwidth and ETA indicator. */
-bool AcqTextStatus::Pulse(pkgAcquire *Owner, download_manager &manager)
+void AcqTextStatus::Pulse(pkgAcquire *Owner, download_manager &manager,
+			  const sigc::slot1<void, bool> &k)
 {
   TotalBytes=manager.get_total_bytes();
   TotalItems=manager.get_total_items();
@@ -159,7 +166,10 @@
   CurrentCPS=manager.get_currentCPS();
 
    if (Quiet > 0)
-      return true;
+     {
+       k(true);
+       return;
+     }
    
    enum {Long = 0,Medium,Short} Mode = Long;
    
@@ -269,13 +279,15 @@
    
    manager.set_update(false);
 
-   return true;
+   k(true);
 }
 									/*}}}*/
 // AcqTextStatus::MediaChange - Media need to be swapped		/*{{{*/
 // ---------------------------------------------------------------------
 /* Prompt for a media swap */
-bool AcqTextStatus::MediaChange(string Media,string Drive, download_manager &manager)
+void AcqTextStatus::MediaChange(string Media, string Drive,
+				download_manager &manager,
+				const sigc::slot1<void, bool> &k)
 {
    if (Quiet <= 0)
       cout << '\r' << BlankLine << '\r';
@@ -288,7 +300,7 @@
       read(STDIN_FILENO,&C,1);
    
    manager.set_update(true);
-   return true;
+   k(true);
 }
 									/*}}}*/
 

Modified: branches/aptitude-0.3/aptitude/src/generic/acqprogress.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/acqprogress.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/acqprogress.h	Fri Sep  9 21:48:05 2005
@@ -11,6 +11,7 @@
 #define ACQPROGRESS_H
 
 #include <apt-pkg/acquire.h>
+#include <sigc++/slot.h>
 #include <sigc++/trackable.h>
 
 class download_manager;
@@ -32,15 +33,17 @@
 
    public:
    
-   virtual bool MediaChange(std::string Media,std::string Drive, download_manager &manager);
+   virtual void MediaChange(std::string Media,std::string Drive, download_manager &manager,
+			    const sigc::slot1<void, bool> &k);
    virtual void IMSHit(pkgAcquire::ItemDesc &Itm, download_manager &manager);
    virtual void Fetch(pkgAcquire::ItemDesc &Itm, download_manager &manager);
    virtual void Done(pkgAcquire::ItemDesc &Itm, download_manager &manager);
    virtual void Fail(pkgAcquire::ItemDesc &Itm, download_manager &manager);
    virtual void Start(download_manager &manager);
-   virtual void Stop(download_manager &manager);
-   
-   bool Pulse(pkgAcquire *Owner, download_manager &manager);
+   virtual void Stop(download_manager &manager, const sigc::slot0<void> &k);
+
+   void Pulse(pkgAcquire *Owner, download_manager &manager,
+	      const sigc::slot1<void, bool> &k);
 
    AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet);
 



More information about the Aptitude-svn-commit mailing list