function_caller.h
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       // notify all threads that are locked on condition variable
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       //printf("FunctionCaller ADD    ==> %5zu\n", queue.size());
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           // wait for condition if queue is empty
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           //printf("FunctionCaller REMOVE ==> %5zu\n", queue.size());
00075         }
00076         // call actual function
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


megatree_core
Author(s): Stuart Glaser
autogenerated on Mon Dec 2 2013 13:01:15