[Aptitude-svn-commit] r4041 - in branches/aptitude-0.3/aptitude: .
src
Daniel Burrows
dburrows at costa.debian.org
Fri Sep 2 23:57:02 UTC 2005
Author: dburrows
Date: Fri Sep 2 23:56:59 2005
New Revision: 4041
Added:
branches/aptitude-0.3/aptitude/src/download_thread.cc
branches/aptitude-0.3/aptitude/src/download_thread.h
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/Makefile.am
Log:
Write harness code for running downloads in the background.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Fri Sep 2 23:56:59 2005
@@ -1,5 +1,9 @@
2005-09-02 Daniel Burrows <dburrows at debian.org>
+ * src/Makefile.am, src/download_thread.cc, src/download_thread.h:
+
+ Write harness code for running downloads in the background.
+
* src/generic/threads.h:
Fix some silly compilation errors; make all broken-out box
Modified: branches/aptitude-0.3/aptitude/src/Makefile.am
==============================================================================
--- branches/aptitude-0.3/aptitude/src/Makefile.am (original)
+++ branches/aptitude-0.3/aptitude/src/Makefile.am Fri Sep 2 23:56:59 2005
@@ -37,6 +37,8 @@
download_list.cc \
download_screen.h\
download_screen.cc\
+ download_thread.h\
+ download_thread.cc\
download_manager.h\
download_manager.cc\
edit_pkg_hier.h \
Added: branches/aptitude-0.3/aptitude/src/download_thread.cc
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/download_thread.cc Fri Sep 2 23:56:59 2005
@@ -0,0 +1,160 @@
+// download_thread.cc
+//
+// Copyright (C) 2005 Daniel Burrows
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#include "download_thread.h"
+
+#include <vscreen/vscreen.h>
+
+#include <sigc++/bind.h>
+#include <sigc++/slot.h>
+#include <sigc++/functors/mem_fun.h>
+
+template<typename RVal>
+class background_execute : public vscreen_event
+{
+ sigc::slot0<RVal> slot;
+
+ threads::box<RVal> &return_box;
+public:
+ background_execute(const sigc::slot0<RVal> &_slot,
+ threads::box<RVal> &_return_box)
+ :slot(_slot), return_box(_return_box)
+ {
+ }
+
+ void dispatch()
+ {
+ return_box.put(slot());
+ }
+};
+
+template<>
+class background_execute<void> : public vscreen_event
+{
+ sigc::slot0<void> slot;
+ threads::box<void> &return_box;
+public:
+ background_execute(const sigc::slot0<void> &_slot,
+ threads::box<void> &_return_box)
+ :slot(_slot), return_box(_return_box)
+ {
+ }
+
+ void dispatch()
+ {
+ slot();
+ return_box.put();
+ }
+};
+
+/** Run the given function call in the foreground and return its value. */
+template<typename RVal>
+static
+RVal do_foreground_execute(pkgAcquireStatus *acq,
+ RVal (pkgAcquireStatus::* fun) ())
+{
+ threads::box<RVal> return_box;
+
+ vscreen_post_event(new background_execute<RVal>(sigc::mem_fun(acq, fun),
+ return_box));
+
+ return return_box.take();
+}
+
+/** Run the given function call in the foreground and return its value. */
+template<typename RVal, typename Arg0>
+static
+RVal do_foreground_execute(pkgAcquireStatus *acq,
+ Arg0 arg0,
+ RVal (pkgAcquireStatus::* fun) (Arg0))
+{
+ threads::box<RVal> return_box;
+
+ vscreen_post_event(new background_execute<RVal>(bind(sigc::mem_fun(acq, fun), arg0),
+ return_box));
+
+ return return_box.take();
+}
+
+/** Run the given function call in the foreground and return its value. */
+template<typename RVal, typename Arg0, typename Arg1>
+static
+RVal do_foreground_execute(pkgAcquireStatus *acq,
+ Arg0 arg0,
+ Arg1 arg1,
+ RVal (pkgAcquireStatus::* fun) (Arg0, Arg1))
+{
+ threads::box<RVal> return_box;
+
+ vscreen_post_event(new background_execute<RVal>(bind(sigc::mem_fun(acq, fun), arg0, arg1),
+ return_box));
+
+ return return_box.take();
+}
+
+void background_status::Fetched(unsigned long Size,
+ unsigned long ResumePoint)
+{
+ do_foreground_execute(real_status, Size, ResumePoint, &pkgAcquireStatus::Fetched);
+}
+
+bool background_status::MediaChange(std::string Media, std::string Drive)
+{
+ return do_foreground_execute(real_status, Media, Drive, &pkgAcquireStatus::MediaChange);
+}
+
+void background_status::IMSHit(pkgAcquire::ItemDesc &item)
+{
+ do_foreground_execute<void, pkgAcquire::ItemDesc &>(real_status, item, &pkgAcquireStatus::IMSHit);
+}
+
+void background_status::Fetch(pkgAcquire::ItemDesc &item)
+{
+ do_foreground_execute<void, pkgAcquire::ItemDesc &>(real_status, item, &pkgAcquireStatus::Fetch);
+}
+
+void background_status::Done(pkgAcquire::ItemDesc &item)
+{
+ do_foreground_execute<void, pkgAcquire::ItemDesc &>(real_status, item, &pkgAcquireStatus::Done);
+}
+
+void background_status::Fail(pkgAcquire::ItemDesc &item)
+{
+ do_foreground_execute<void, pkgAcquire::ItemDesc &>(real_status, item, &pkgAcquireStatus::Fail);
+}
+
+bool background_status::Pulse(pkgAcquire *Owner)
+{
+ return do_foreground_execute(real_status, Owner, &pkgAcquireStatus::Pulse);
+}
+
+void background_status::Start()
+{
+ do_foreground_execute(real_status, &pkgAcquireStatus::Start);
+}
+
+void background_status::Stop()
+{
+ do_foreground_execute(real_status, &pkgAcquireStatus::Stop);
+}
+
+void download_thread::operator()()
+{
+ continuation(this, acq->Run());
+}
Added: branches/aptitude-0.3/aptitude/src/download_thread.h
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/download_thread.h Fri Sep 2 23:56:59 2005
@@ -0,0 +1,106 @@
+// download_thread -*-c++-*-
+//
+// Copyright (C) 2005 Daniel Burrows
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#ifndef DOWNLOAD_THREAD_H
+#define DOWNLOAD_THREAD_H
+
+#include <apt-pkg/acquire.h>
+#include <apt-pkg/error.h>
+
+#include <generic/threads.h>
+
+#include <sigc++/slot.h>
+
+/** A proxy status object that posts messages to the main thread.
+ * Each message "blocks" the download until the user deals with it,
+ * just as if it was running in the main thread (I'm not sure
+ * anything else is safe).
+ *
+ * This object does NOT own the encapsulated status object and will
+ * NOT delete it.
+ */
+class background_status : public pkgAcquireStatus
+{
+ pkgAcquireStatus *real_status;
+public:
+ virtual void Fetched(unsigned long Size, unsigned long ResumePoint);
+ virtual bool MediaChange(std::string Media, std::string Drive);
+ virtual void IMSHit(pkgAcquire::ItemDesc &);
+ virtual void Fetch(pkgAcquire::ItemDesc &);
+ virtual void Done(pkgAcquire::ItemDesc &);
+ virtual void Fail(pkgAcquire::ItemDesc &);
+ virtual bool Pulse(pkgAcquire *Owner);
+ virtual void Start();
+ virtual void Stop();
+
+ background_status(pkgAcquireStatus *_real_status)
+ :real_status(_real_status)
+ {
+ }
+};
+
+/** The thread that performs the download. */
+class download_thread
+{
+ threads::box<bool> cancelled;
+
+ /** The bundled pkgAcquire object. It should have been initialized
+ * using a background_status wrapper as above, and you should
+ * join() this thread before deleting it.
+ */
+ pkgAcquire *acq;
+
+ /** The continuation of this download, called with this thread and
+ * the result of the run as parameters.
+ */
+ sigc::slot2<void, download_thread *, pkgAcquire::RunResult> continuation;
+
+ threads::thread *t;
+
+ download_thread(const download_thread &other);
+ download_thread &operator=(const download_thread &other);
+public:
+ download_thread(pkgAcquire *_acq,
+ const sigc::slot2<void, download_thread *, pkgAcquire::RunResult> &_continuation)
+ : cancelled(false), acq(_acq), continuation(_continuation), t(NULL)
+ {
+ }
+
+ ~download_thread()
+ {
+ delete t;
+ }
+
+ void operator()();
+
+ void start()
+ {
+ if(t != NULL)
+ _error->Error("Attempt to start a download thread twice!");
+ else
+ t = new threads::thread(threads::noncopy_bootstrap<download_thread>(*this));
+ }
+
+ void join()
+ {
+ t->join();
+ }
+};
+
+#endif // DOWNLOAD_THREAD_H
More information about the Aptitude-svn-commit
mailing list