Go to the documentation of this file.00001 #ifndef MEGATREE_FUNCTION_CALLER_H
00002 #define MEGATREE_FUNCTION_CALLER_H
00003
00004
00005 #include <boost/bind.hpp>
00006 #include <boost/function.hpp>
00007 #include <boost/thread/thread.hpp>
00008 #include <boost/thread/mutex.hpp>
00009 #include <boost/thread/condition.hpp>
00010 #include <vector>
00011
00012 namespace megatree
00013 {
00014
00015 class FunctionCaller
00016 {
00017 public:
00018 FunctionCaller(unsigned thread_pool_size=1)
00019 :running(true)
00020 {
00021 threads.resize(thread_pool_size);
00022 for (unsigned i=0; i<threads.size(); i++)
00023 threads[i] = new boost::thread(boost::bind(&FunctionCaller::threadLoop, this, i));
00024 }
00025
00026
00027 ~FunctionCaller()
00028 {
00029
00030 {
00031 boost::mutex::scoped_lock lock(mutex);
00032 running = false;
00033 condition.notify_all();
00034 }
00035
00036 for (unsigned i=0; i<threads.size(); i++)
00037 {
00038 threads[i]->join();
00039 delete threads[i];
00040 }
00041 }
00042
00043
00044
00045 void addFunction(boost::function<void(void)> func)
00046 {
00047 boost::mutex::scoped_lock lock(mutex);
00048 queue.push_front(func);
00049
00050 condition.notify_one();
00051 }
00052
00053
00054 void threadLoop(unsigned i)
00055 {
00056 while (true)
00057 {
00058 boost::function<void(void)> f;
00059 {
00060
00061 boost::mutex::scoped_lock lock(mutex);
00062 while (queue.empty())
00063 {
00064 if (!running)
00065 return;
00066 condition.wait(lock);
00067 }
00068 if (!running)
00069 return;
00070
00071 assert(!queue.empty());
00072 f = queue.back();
00073 queue.pop_back();
00074
00075 }
00076
00077 f();
00078 }
00079 }
00080
00081
00082 private:
00083 boost::condition condition;
00084
00085 bool running;
00086 std::list<boost::function<void(void)> > queue;
00087 boost::mutex mutex;
00088 std::vector<boost::thread*> threads;
00089 };
00090
00091 }
00092 #endif