aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-08-07 11:22:39 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-08-07 11:22:39 +0000
commit85747c54f286921fd79db61c114ed0891fdc8210 (patch)
treeed7dd64650f36e01f8331d268e5a5f500ecbf0f1
parentbc5ab89c7e99a5248341b59064856ab258f9c888 (diff)
downloadpaludis-85747c54f286921fd79db61c114ed0891fdc8210.tar.gz
paludis-85747c54f286921fd79db61c114ed0891fdc8210.tar.xz
oops
-rw-r--r--paludis/util/future-impl.hh107
1 files changed, 107 insertions, 0 deletions
diff --git a/paludis/util/future-impl.hh b/paludis/util/future-impl.hh
new file mode 100644
index 0000000..fa59f65
--- /dev/null
+++ b/paludis/util/future-impl.hh
@@ -0,0 +1,107 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_FUTURE_IMPL_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_FUTURE_IMPL_HH 1
+
+#include <paludis/util/future.hh>
+#include <paludis/util/mutex.hh>
+#include <paludis/util/condition_variable.hh>
+#include <paludis/util/tr1_memory.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+
+namespace paludis
+{
+ template <typename T_>
+ void adapt_for_future(
+ tr1::function<T_ () throw ()> f,
+ tr1::shared_ptr<tr1::shared_ptr<T_> > result,
+ tr1::shared_ptr<Mutex> mutex,
+ tr1::shared_ptr<ConditionVariable> condition);
+
+ template <>
+ template <typename T_>
+ struct Implementation<Future<T_> >
+ {
+ const tr1::function<T_ () throw ()> f;
+ mutable tr1::shared_ptr<tr1::shared_ptr<T_> > result;
+ mutable tr1::shared_ptr<Mutex> mutex;
+ mutable tr1::shared_ptr<ConditionVariable> condition;
+
+ Implementation(const tr1::function<T_ () throw ()> & fn) :
+ f(fn),
+ result(new tr1::shared_ptr<T_>),
+ mutex(new Mutex),
+ condition(new ConditionVariable)
+ {
+ FutureActionQueue::get_instance()->enqueue(tr1::bind(paludis::adapt_for_future<T_>, f, result, mutex, condition));
+ }
+ };
+}
+
+template <typename T_>
+paludis::Future<T_>::Future(const tr1::function<T_ () throw ()> & f) :
+ PrivateImplementationPattern<Future<T_> >(new Implementation<Future<T_> >(f))
+{
+}
+
+template <typename T_>
+paludis::Future<T_>::~Future()
+{
+ Lock l(*_imp->mutex);
+ if (! *_imp->result)
+ {
+ _imp->result->reset(new T_(_imp->f()));
+ _imp->condition->broadcast();
+ }
+}
+
+template <typename T_>
+T_
+paludis::Future<T_>::operator() () const
+{
+ Lock l(*_imp->mutex);
+
+ if (! *_imp->result)
+ {
+ _imp->result->reset(new T_(_imp->f()));
+ _imp->condition->broadcast();
+ }
+
+ return **_imp->result;
+}
+
+template <typename T_>
+void paludis::adapt_for_future(
+ tr1::function<T_ () throw ()> f,
+ tr1::shared_ptr<tr1::shared_ptr<T_> > result,
+ tr1::shared_ptr<Mutex> mutex,
+ tr1::shared_ptr<ConditionVariable> condition)
+{
+ TryLock l(*mutex);
+ if (l())
+ {
+ if (! *result)
+ result->reset(new T_(f()));
+ condition->broadcast();
+ }
+}
+
+#endif