aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-08-06 19:57:27 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-08-06 19:57:27 +0000
commitfd692a5b206d849dbd4f1b717bb57d2b8f18ec65 (patch)
tree4f000b8c9d053174bf5556b354cd3e21ca2cfd43
parente2871f89e85db27bf875f4b2262a625e57884c0c (diff)
downloadpaludis-fd692a5b206d849dbd4f1b717bb57d2b8f18ec65.tar.gz
paludis-fd692a5b206d849dbd4f1b717bb57d2b8f18ec65.tar.xz
More threading
-rw-r--r--paludis/query.cc57
-rw-r--r--paludis/util/files.m41
-rw-r--r--paludis/util/future.cc37
-rw-r--r--paludis/util/future.hh57
-rw-r--r--paludis/util/future_TEST.cc68
-rw-r--r--paludis/util/idle_action_pool.cc2
6 files changed, 197 insertions, 25 deletions
diff --git a/paludis/query.cc b/paludis/query.cc
index 999727d..afba7f8 100644
--- a/paludis/query.cc
+++ b/paludis/query.cc
@@ -23,6 +23,7 @@
#include <paludis/util/sequence.hh>
#include <paludis/util/set.hh>
#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/future-impl.hh>
#include <paludis/package_database.hh>
#include <paludis/environment.hh>
#include <paludis/match_package.hh>
@@ -337,75 +338,83 @@ namespace
tr1::shared_ptr<RepositoryNameSequence>
repositories(const Environment & e) const
{
- tr1::shared_ptr<RepositoryNameSequence> r1(q1->repositories(e)), r2(q2->repositories(e));
+ Future<tr1::shared_ptr<RepositoryNameSequence> >
+ r1(tr1::bind(&QueryDelegate::repositories, q1, tr1::cref(e))),
+ r2(tr1::bind(&QueryDelegate::repositories, q2, tr1::cref(e)));
- if (r1 && r2)
+ if (r1() && r2())
{
- std::set<RepositoryName, RepositoryNameComparator> s1(r1->begin(), r1->end()), s2(r2->begin(), r2->end());
+ std::set<RepositoryName, RepositoryNameComparator> s1(r1()->begin(), r1()->end()), s2(r2()->begin(), r2()->end());
tr1::shared_ptr<RepositoryNameSequence> result(new RepositoryNameSequence);
std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), result->back_inserter(),
RepositoryNameComparator());
return result;
}
- else if (r1)
- return r1;
+ else if (r1())
+ return r1();
else
- return r2;
+ return r2();
}
tr1::shared_ptr<CategoryNamePartSet>
categories(const Environment & e, tr1::shared_ptr<const RepositoryNameSequence> r) const
{
- tr1::shared_ptr<CategoryNamePartSet> r1(q1->categories(e, r)), r2(q2->categories(e, r));
+ Future<tr1::shared_ptr<CategoryNamePartSet> >
+ r1(tr1::bind(&QueryDelegate::categories, q1, tr1::cref(e), tr1::cref(r))),
+ r2(tr1::bind(&QueryDelegate::categories, q2, tr1::cref(e), tr1::cref(r)));
- if (r1 && r2)
+ if (r1() && r2())
{
tr1::shared_ptr<CategoryNamePartSet> result(new CategoryNamePartSet);
- std::set_intersection(r1->begin(), r1->end(), r2->begin(), r2->end(), result->inserter());
+ std::set_intersection(r1()->begin(), r1()->end(), r2()->begin(), r2()->end(), result->inserter());
return result;
}
- else if (r1)
- return r1;
+ else if (r1())
+ return r1();
else
- return r2;
+ return r2();
}
tr1::shared_ptr<QualifiedPackageNameSet>
packages(const Environment & e, tr1::shared_ptr<const RepositoryNameSequence> r,
tr1::shared_ptr<const CategoryNamePartSet> c) const
{
- tr1::shared_ptr<QualifiedPackageNameSet> r1(q1->packages(e, r, c)), r2(q2->packages(e, r, c));
+ Future<tr1::shared_ptr<QualifiedPackageNameSet> >
+ r1(tr1::bind(&QueryDelegate::packages, q1, tr1::cref(e), tr1::cref(r), tr1::cref(c))),
+ r2(tr1::bind(&QueryDelegate::packages, q2, tr1::cref(e), tr1::cref(r), tr1::cref(c)));
- if (r1 && r2)
+ if (r1() && r2())
{
tr1::shared_ptr<QualifiedPackageNameSet> result(new QualifiedPackageNameSet);
- std::set_intersection(r1->begin(), r1->end(), r2->begin(), r2->end(), result->inserter());
+ std::set_intersection(r1()->begin(), r1()->end(), r2()->begin(), r2()->end(), result->inserter());
return result;
}
- else if (r1)
- return r1;
+ else if (r1())
+ return r1();
else
- return r2;
+ return r2();
}
tr1::shared_ptr<PackageIDSequence>
ids(const Environment & e, tr1::shared_ptr<const RepositoryNameSequence> r,
tr1::shared_ptr<const QualifiedPackageNameSet> q) const
{
- tr1::shared_ptr<PackageIDSequence> r1(q1->ids(e, r, q)), r2(q2->ids(e, r, q));
+ Future<tr1::shared_ptr<PackageIDSequence> >
+ r1(tr1::bind(&QueryDelegate::ids, q1, tr1::cref(e), tr1::cref(r), tr1::cref(q))),
+ r2(tr1::bind(&QueryDelegate::ids, q2, tr1::cref(e), tr1::cref(r), tr1::cref(q)));
- if (r1 && r2)
+ if (r1() && r2())
{
std::set<tr1::shared_ptr<const PackageID>, PackageIDSetComparator>
- s1(r1->begin(), r1->end()), s2(r2->begin(), r2->end());
+ s1(r1()->begin(), r1()->end()), s2(r2()->begin(), r2()->end());
tr1::shared_ptr<PackageIDSequence> result(new PackageIDSequence);
std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), result->back_inserter(), PackageIDSetComparator());
return result;
}
- else if (r1)
- return r1;
+ else if (r1())
+ return r1();
else
- return r2;
+ return r2();
}
};
}
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index 0c2d42e..f6466de 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -17,6 +17,7 @@ add(`dir_iterator', `hh', `cc', `test', `testscript')
add(`exception', `hh', `cc')
add(`fast_unique_copy', `hh', `test')
add(`fd_output_stream', `hh')
+add(`future', `hh', `impl', `cc', `test')
add(`fs_entry', `hh', `cc', `fwd', `test', `testscript')
add(`fd_holder', `hh')
add(`graph', `hh', `cc', `impl', `test')
diff --git a/paludis/util/future.cc b/paludis/util/future.cc
new file mode 100644
index 0000000..4f21547
--- /dev/null
+++ b/paludis/util/future.cc
@@ -0,0 +1,37 @@
+/* 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
+ */
+
+#include <paludis/util/future.hh>
+#include <paludis/util/future-impl.hh>
+#include <paludis/util/instantiation_policy-impl.hh>
+#include <paludis/util/system.hh>
+
+using namespace paludis;
+
+template class InstantiationPolicy<FutureActionQueue, instantiation_method::SingletonTag>;
+
+FutureActionQueue::FutureActionQueue() :
+ ActionQueue(destringify<int>(getenv_with_default("PALUDIS_FUTURE_THREAD_COUNT", "2")), true)
+{
+}
+
+FutureActionQueue::~FutureActionQueue()
+{
+}
+
diff --git a/paludis/util/future.hh b/paludis/util/future.hh
new file mode 100644
index 0000000..64734be
--- /dev/null
+++ b/paludis/util/future.hh
@@ -0,0 +1,57 @@
+/* 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_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_FUTURE_HH 1
+
+#include <paludis/util/attributes.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/action_queue.hh>
+
+namespace paludis
+{
+ class PALUDIS_VISIBLE FutureActionQueue :
+ public ActionQueue,
+ public InstantiationPolicy<FutureActionQueue, instantiation_method::SingletonTag>
+ {
+ friend class InstantiationPolicy<FutureActionQueue, instantiation_method::SingletonTag>;
+
+ public:
+ FutureActionQueue();
+ ~FutureActionQueue();
+ };
+
+ template <typename T_>
+ class PALUDIS_VISIBLE Future :
+ private PrivateImplementationPattern<Future<T_> >
+ {
+ private:
+ using PrivateImplementationPattern<Future<T_> >::_imp;
+
+ public:
+ Future(const tr1::function<T_ () throw ()> &);
+ ~Future();
+
+ T_ operator() () const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+}
+
+#endif
diff --git a/paludis/util/future_TEST.cc b/paludis/util/future_TEST.cc
new file mode 100644
index 0000000..6353b02
--- /dev/null
+++ b/paludis/util/future_TEST.cc
@@ -0,0 +1,68 @@
+/* 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
+ */
+
+#include <paludis/util/future-impl.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace paludis;
+using namespace test;
+
+namespace
+{
+ int f()
+ {
+ return 42;
+ }
+
+ int g()
+ {
+ Future<int> r1(&f), r2(&f), r3(&f), r4(&f);
+ return r1() + r2() + r3() - r4();
+ }
+}
+
+namespace test_cases
+{
+ struct FutureTest : TestCase
+ {
+ FutureTest() : TestCase("future") { }
+
+ void run()
+ {
+ Future<int> f1(&f);
+ TEST_CHECK_EQUAL(f1(), 42);
+ TEST_CHECK_EQUAL(f1(), 42);
+ }
+ } test_future;
+
+ struct FutureFutureTest : TestCase
+ {
+ FutureFutureTest() : TestCase("future future") { }
+
+ void run()
+ {
+ Future<int> f1(&g), f2(&g);
+ TEST_CHECK_EQUAL(f1(), 84);
+ TEST_CHECK_EQUAL(f2(), 84);
+ }
+ } test_future_future;
+}
+
+
diff --git a/paludis/util/idle_action_pool.cc b/paludis/util/idle_action_pool.cc
index 2cfd7d5..5200760 100644
--- a/paludis/util/idle_action_pool.cc
+++ b/paludis/util/idle_action_pool.cc
@@ -75,7 +75,7 @@ namespace paludis
ActionQueue pool;
Implementation() :
- pool(destringify<int>(getenv_with_default("PALUDIS_IDLE_THREAD_COUNT", "5")), true)
+ pool(destringify<int>(getenv_with_default("PALUDIS_IDLE_THREAD_COUNT", "2")), true)
{
}