You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

scheduler.h 2.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright (c) 2015 The Bitcoin Core developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #ifndef BITCOIN_SCHEDULER_H
  5. #define BITCOIN_SCHEDULER_H
  6. //
  7. // NOTE:
  8. // boost::thread / boost::chrono should be ported to std::thread / std::chrono
  9. // when we support C++11.
  10. //
  11. #include <boost/chrono/chrono.hpp>
  12. #include <boost/thread.hpp>
  13. #include <map>
  14. //
  15. // Simple class for background tasks that should be run
  16. // periodically or once "after a while"
  17. //
  18. // Usage:
  19. //
  20. // CScheduler* s = new CScheduler();
  21. // s->scheduleFromNow(doSomething, 11); // Assuming a: void doSomething() { }
  22. // s->scheduleFromNow(std::bind(Class::func, this, argument), 3);
  23. // boost::thread* t = new boost::thread(boost::bind(CScheduler::serviceQueue, s));
  24. //
  25. // ... then at program shutdown, clean up the thread running serviceQueue:
  26. // t->interrupt();
  27. // t->join();
  28. // delete t;
  29. // delete s; // Must be done after thread is interrupted/joined.
  30. //
  31. class CScheduler
  32. {
  33. public:
  34. CScheduler();
  35. ~CScheduler();
  36. typedef std::function<void(void)> Function;
  37. // Call func at/after time t
  38. void schedule(Function f, boost::chrono::system_clock::time_point t);
  39. // Convenience method: call f once deltaSeconds from now
  40. void scheduleFromNow(Function f, int64_t deltaMilliSeconds);
  41. // Another convenience method: call f approximately
  42. // every deltaSeconds forever, starting deltaSeconds from now.
  43. // To be more precise: every time f is finished, it
  44. // is rescheduled to run deltaSeconds later. If you
  45. // need more accurate scheduling, don't use this method.
  46. void scheduleEvery(Function f, int64_t deltaMilliSeconds);
  47. // To keep things as simple as possible, there is no unschedule.
  48. // Services the queue 'forever'. Should be run in a thread,
  49. // and interrupted using boost::interrupt_thread
  50. void serviceQueue();
  51. // Tell any threads running serviceQueue to stop as soon as they're
  52. // done servicing whatever task they're currently servicing (drain=false)
  53. // or when there is no work left to be done (drain=true)
  54. void stop(bool drain=false);
  55. // Returns number of tasks waiting to be serviced,
  56. // and first and last task times
  57. size_t getQueueInfo(boost::chrono::system_clock::time_point &first,
  58. boost::chrono::system_clock::time_point &last) const;
  59. private:
  60. std::multimap<boost::chrono::system_clock::time_point, Function> taskQueue;
  61. boost::condition_variable newTaskScheduled;
  62. mutable boost::mutex newTaskMutex;
  63. int nThreadsServicingQueue;
  64. bool stopRequested;
  65. bool stopWhenEmpty;
  66. bool shouldStop() { return stopRequested || (stopWhenEmpty && taskQueue.empty()); }
  67. };
  68. #endif