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

Daniel Burrows dburrows at costa.debian.org
Fri Sep 2 23:20:23 UTC 2005


Author: dburrows
Date: Fri Sep  2 23:20:21 2005
New Revision: 4039

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/threads.h
Log:
Add a helper for noncopyable functors; specialize the box for void.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Fri Sep  2 23:20:21 2005
@@ -1,5 +1,11 @@
 2005-09-02  Daniel Burrows  <dburrows at debian.org>
 
+	* src/generic/threads.h:
+
+	  Add a helper class to bootstrap noncopyable functors in threads,
+	  and write an explicit specialization of threads::box for void
+	  that acts as a "baton repository".
+
 	* src/cmdline/cmdline_update.cc, src/download.cc, src/download.h:
 
 	  Split the package-list updating code around the download

Modified: branches/aptitude-0.3/aptitude/src/generic/threads.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/threads.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/threads.h	Fri Sep  2 23:20:21 2005
@@ -210,6 +210,26 @@
     }
   };
 
+  // If you have a necessarily noncopyable object to bootstrap a
+  // thread with, you can pass it through the following structure; be
+  // warned, though, that this won't delete it when the operation
+  // completes.
+  template<typename F>
+  struct noncopy_bootstrap
+  {
+    F &f;
+  public:
+    noncopy_bootstrap(F &_f)
+      :f(_f)
+    {
+    }
+
+    void operator()()
+    {
+      f();
+    }
+  };
+
   class condition;
 
   // The mutex abstraction
@@ -507,6 +527,9 @@
 
     condition cond;
     mutex m;
+
+    box(const box &other);
+    box &operator=(const box &other);
   public:
     /** Create an empty box. */
     box()
@@ -566,6 +589,50 @@
     void box::update(const Mutator &m);
   };
 
+  /** A box specialized for 'void'; may make it easier to write
+   *  other templated classes.  Could maybe just be a mutex, but I
+   *  don't think you can quite mimic the box API that way.
+   */
+  template<>
+  class box<void>
+  {
+    bool filled;
+    mutex m;
+    condition c;
+  public:
+    box()
+      :filled(false)
+    {
+    }
+
+    void take();
+
+    void put();
+
+    bool try_take();
+    bool try_put();
+
+    bool timed_take(const timespec &until);
+    bool timed_put(const timespec &until);
+
+    template<typename Mutator>
+    void box::update(const Mutator &m)
+    {
+      take();
+      try
+	{
+	  m();
+	}
+      catch(...)
+	{
+	  put();
+	  throw;
+	}
+
+      put();
+    }
+  };
+
   /** Internal helper struct. */
   struct bool_ref_pred
   {
@@ -613,6 +680,13 @@
     return rval;
   }
 
+  void box<void>::take
+  {
+    mutex::lock l(m);
+    cond.wait(l, bool_ref_pred(filled));
+    filled = false;
+  }
+
   template<typename T>
   bool box<T>::try_take(T &out)
   {
@@ -628,6 +702,19 @@
       return false;
   }
 
+  bool box<void>::try_take()
+  {
+    mutex::lock l(m);
+
+    if(filled)
+      {
+	filled = false;
+	return true;
+      }
+    else
+      return false;
+  }
+
   template<typename T>
   bool box<T>::timed_take(T &out, const timespec &until)
   {
@@ -643,6 +730,19 @@
       return false;
   }
 
+  bool box<void>::timed_take(const timespec &until)
+  {
+    mutex::lock l(m);
+
+    if(cond.timed_wait(l, until, bool_ref_pred(filled)))
+      {
+	filled = false;
+	return true;
+      }
+    else
+      return false;
+  }
+
   template<typename T>
   void box<T>::put(const T &new_val)
   {
@@ -655,6 +755,16 @@
     cond.wake_one();
   }
 
+  void box<void>::put()
+  {
+    mutex::lock l(m);
+
+    cond.wait(l, not_bool_ref_pred(filled));
+
+    filled = true;
+    cond.wake_one();
+  }
+
   template<typename T>
   bool box<T>::try_put(const T &new_val)
   {
@@ -671,6 +781,20 @@
       return false;
   }
 
+  bool box<void>::try_put()
+  {
+    mutex::lock l(m);
+
+    if(!filled)
+      {
+	filed = true;
+	cond.wake_one();
+	return true;
+      }
+    else
+      return false;
+  }
+
   template<typename T>
   bool box<T>::timed_put(const T &new_val, const timespec &until)
   {
@@ -687,6 +811,20 @@
       return false;
   }
 
+  bool box<void>::timed_put(const timespec &until)
+  {
+    mutex::lock l(m);
+
+    if(cond.timed_wait(l, until, not_bool_ref_pred(filled)))
+      {
+	filled = true;
+	cond.wake_one();
+	return true;
+      }
+    else
+      return false;
+  }
+
   template<typename T>
   template<typename Mutator>
   void box<T>::update(const Mutator &m)



More information about the Aptitude-svn-commit mailing list