mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 00:56:44 +01:00
83 lines
3.0 KiB
C++
83 lines
3.0 KiB
C++
// thread_pool.h
|
|
|
|
/* Copyright 2009 10gen Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <boost/function.hpp>
|
|
#include <boost/bind.hpp>
|
|
#undef assert
|
|
#define assert MONGO_assert
|
|
|
|
namespace mongo {
|
|
|
|
namespace threadpool {
|
|
class Worker;
|
|
|
|
typedef boost::function<void(void)> Task; //nullary function or functor
|
|
|
|
// exported to the mongo namespace
|
|
class ThreadPool : boost::noncopyable{
|
|
public:
|
|
explicit ThreadPool(int nThreads=8);
|
|
|
|
// blocks until all tasks are complete (tasks_remaining() == 0)
|
|
// You should not call schedule while in the destructor
|
|
~ThreadPool();
|
|
|
|
// blocks until all tasks are complete (tasks_remaining() == 0)
|
|
// does not prevent new tasks from being scheduled so could wait forever.
|
|
// Also, new tasks could be scheduled after this returns.
|
|
void join();
|
|
|
|
|
|
// task will be copied a few times so make sure it's relatively cheap
|
|
void schedule(Task task);
|
|
|
|
// Helpers that wrap schedule and boost::bind.
|
|
// Functor and args will be copied a few times so make sure it's relatively cheap
|
|
template<typename F, typename A>
|
|
void schedule(F f, A a){ schedule(boost::bind(f,a)); }
|
|
template<typename F, typename A, typename B>
|
|
void schedule(F f, A a, B b){ schedule(boost::bind(f,a,b)); }
|
|
template<typename F, typename A, typename B, typename C>
|
|
void schedule(F f, A a, B b, C c){ schedule(boost::bind(f,a,b,c)); }
|
|
template<typename F, typename A, typename B, typename C, typename D>
|
|
void schedule(F f, A a, B b, C c, D d){ schedule(boost::bind(f,a,b,c,d)); }
|
|
template<typename F, typename A, typename B, typename C, typename D, typename E>
|
|
void schedule(F f, A a, B b, C c, D d, E e){ schedule(boost::bind(f,a,b,c,d,e)); }
|
|
|
|
|
|
int tasks_remaining() { return _tasksRemaining; }
|
|
|
|
private:
|
|
mongo::mutex _mutex;
|
|
boost::condition _condition;
|
|
|
|
list<Worker*> _freeWorkers; //used as LIFO stack (always front)
|
|
list<Task> _tasks; //used as FIFO queue (push_back, pop_front)
|
|
int _tasksRemaining; // in queue + currently processing
|
|
int _nThreads; // only used for sanity checking. could be removed in the future.
|
|
|
|
// should only be called by a worker from the worker's thread
|
|
void task_done(Worker* worker);
|
|
friend class Worker;
|
|
};
|
|
|
|
} //namespace threadpool
|
|
|
|
using threadpool::ThreadPool;
|
|
|
|
} //namespace mongo
|