[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