diff options
author | 2009-12-28 15:24:05 +0000 | |
---|---|---|
committer | 2009-12-28 15:24:05 +0000 | |
commit | cc8e0f1a8e2396df9402897bb358ae1544d96467 (patch) | |
tree | ea094e7fc6ee00092f6116658442c7c922d0dfe2 /paludis | |
parent | ed20e3bc7a0fcef8cfd75f07508318f99cb0d7d5 (diff) | |
download | paludis-cc8e0f1a8e2396df9402897bb358ae1544d96467.tar.gz paludis-cc8e0f1a8e2396df9402897bb358ae1544d96467.tar.xz |
Move executors into util
Diffstat (limited to 'paludis')
-rw-r--r-- | paludis/util/executor-fwd.hh | 29 | ||||
-rw-r--r-- | paludis/util/executor.cc | 153 | ||||
-rw-r--r-- | paludis/util/executor.hh | 68 | ||||
-rw-r--r-- | paludis/util/files.m4 | 1 |
4 files changed, 251 insertions, 0 deletions
diff --git a/paludis/util/executor-fwd.hh b/paludis/util/executor-fwd.hh new file mode 100644 index 000000000..b50797629 --- /dev/null +++ b/paludis/util/executor-fwd.hh @@ -0,0 +1,29 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2009 Ciaran McCreesh + * + * 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_EXECUTOR_FWD_HH +#define PALUDIS_GUARD_PALUDIS_UTIL_EXECUTOR_FWD_HH 1 + +namespace paludis +{ + struct Executor; + struct Executive; +} + +#endif diff --git a/paludis/util/executor.cc b/paludis/util/executor.cc new file mode 100644 index 000000000..90fec4ee9 --- /dev/null +++ b/paludis/util/executor.cc @@ -0,0 +1,153 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2009 Ciaran McCreesh + * + * 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/executor.hh> +#include <paludis/util/private_implementation_pattern-impl.hh> +#include <paludis/util/mutex.hh> +#include <paludis/util/condition_variable.hh> +#include <paludis/util/thread.hh> +#include <paludis/util/make_shared_ptr.hh> +#include <map> +#include <list> + +using namespace paludis; + +typedef std::multimap<std::string, std::tr1::shared_ptr<Executive> > Queues; +typedef std::list<std::tr1::shared_ptr<Executive> > ReadyForPost; + +Executive::~Executive() +{ +} + +namespace paludis +{ + template <> + struct Implementation<Executor> + { + int pending; + int active; + int done; + + Queues queues; + ReadyForPost ready_for_post; + Mutex mutex; + ConditionVariable condition; + + Implementation() : + pending(0), + active(0), + done(0) + { + } + }; +} + +Executor::Executor() : + PrivateImplementationPattern<Executor>(new Implementation<Executor>) +{ +} + +Executor::~Executor() +{ +} + +void +Executor::_one(const std::tr1::shared_ptr<Executive> executive) +{ + executive->execute_threaded(); + + Lock lock(_imp->mutex); + _imp->ready_for_post.push_back(executive); + _imp->condition.signal(); +} + + +int +Executor::pending() const +{ + return _imp->pending; +} + +int +Executor::active() const +{ + return _imp->active; +} + +int +Executor::done() const +{ + return _imp->done; +} + +void +Executor::add(const std::tr1::shared_ptr<Executive> & x) +{ + ++_imp->pending; + _imp->queues.insert(std::make_pair(x->queue_name(), x)); +} + +void +Executor::execute() +{ + typedef std::map<std::string, std::tr1::shared_ptr<Thread> > Running; + Running running; + + Lock lock(_imp->mutex); + while (true) + { + bool any(false); + for (Queues::iterator q(_imp->queues.begin()), q_end(_imp->queues.end()) ; + q != q_end ; ) + { + if ((running.end() != running.find(q->first)) || ! q->second->can_run()) + { + ++q; + continue; + } + + ++_imp->active; + --_imp->pending; + q->second->pre_execute_exclusive(); + running.insert(std::make_pair(q->first, make_shared_ptr(new Thread( + std::tr1::bind(&Executor::_one, this, q->second))))); + _imp->queues.erase(q++); + any = true; + } + + if ((! any) && running.empty()) + break; + + _imp->condition.wait(_imp->mutex); + + for (ReadyForPost::iterator p(_imp->ready_for_post.begin()), p_end(_imp->ready_for_post.end()) ; + p != p_end ; ++p) + { + --_imp->active; + ++_imp->done; + running.erase((*p)->queue_name()); + (*p)->post_execute_exclusive(); + } + + _imp->ready_for_post.clear(); + } +} + +template class PrivateImplementationPattern<Executor>; + diff --git a/paludis/util/executor.hh b/paludis/util/executor.hh new file mode 100644 index 000000000..e468de2b4 --- /dev/null +++ b/paludis/util/executor.hh @@ -0,0 +1,68 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2009 Ciaran McCreesh + * + * 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_EXECUTOR_HH +#define PALUDIS_GUARD_PALUDIS_UTIL_EXECUTOR_HH 1 + +#include <paludis/util/executor-fwd.hh> +#include <paludis/util/private_implementation_pattern.hh> +#include <string> +#include <tr1/memory> + +namespace paludis +{ + class PALUDIS_VISIBLE Executive + { + public: + virtual ~Executive() = 0; + + virtual std::string queue_name() const = 0; + virtual std::string unique_id() const = 0; + virtual bool can_run() const = 0; + + virtual void pre_execute_exclusive() = 0; + virtual void execute_threaded() = 0; + virtual void post_execute_exclusive() = 0; + }; + + class PALUDIS_VISIBLE Executor : + private PrivateImplementationPattern<Executor> + { + private: + void _one(const std::tr1::shared_ptr<Executive>); + + public: + Executor(); + ~Executor(); + + int pending() const; + int active() const; + int done() const; + + void add(const std::tr1::shared_ptr<Executive> & x); + + void execute(); + }; + +#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE + extern template class PrivateImplementationPattern<Executor>; +#endif +} + +#endif diff --git a/paludis/util/files.m4 b/paludis/util/files.m4 index 480941548..387a68b79 100644 --- a/paludis/util/files.m4 +++ b/paludis/util/files.m4 @@ -27,6 +27,7 @@ add(`dir_iterator', `hh', `cc', `fwd', `se', `test', `tests add(`discard_output_stream', `hh', `cc') add(`enum_iterator', `hh', `cc', `fwd', `test') add(`exception', `hh', `cc') +add(`executor', `hh', `cc', `fwd') add(`extract_host_from_url', `hh', `cc', `fwd', `test') add(`fast_unique_copy', `hh', `test') add(`forward_parallel_for_each', `hh', `test') |