inline_executor.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright (C) 2014 Vicente J. Botet Escriba
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. //
  6. // 2013/11 Vicente J. Botet Escriba
  7. // first implementation of a simple serial scheduler.
  8. #ifndef BOOST_THREAD_INLINE_EXECUTOR_HPP
  9. #define BOOST_THREAD_INLINE_EXECUTOR_HPP
  10. #include <boost/thread/detail/config.hpp>
  11. #include <boost/thread/detail/delete.hpp>
  12. #include <boost/thread/detail/move.hpp>
  13. #include <boost/thread/executors/work.hpp>
  14. #include <boost/config/abi_prefix.hpp>
  15. namespace boost
  16. {
  17. namespace executors
  18. {
  19. class inline_executor
  20. {
  21. public:
  22. /// type-erasure to store the works to do
  23. typedef executors::work work;
  24. bool closed_;
  25. mutable mutex mtx_;
  26. /**
  27. * Effects: try to execute one task.
  28. * Returns: whether a task has been executed.
  29. * Throws: whatever the current task constructor throws or the task() throws.
  30. */
  31. bool try_executing_one()
  32. {
  33. return false;
  34. }
  35. public:
  36. /// inline_executor is not copyable.
  37. BOOST_THREAD_NO_COPYABLE(inline_executor)
  38. /**
  39. * \b Effects: creates a inline executor that runs closures immediately.
  40. *
  41. * \b Throws: Nothing.
  42. */
  43. inline_executor()
  44. : closed_(false)
  45. {
  46. }
  47. /**
  48. * \b Effects: Destroys the inline executor.
  49. *
  50. * \b Synchronization: The completion of all the closures happen before the completion of the \c inline_executor destructor.
  51. */
  52. ~inline_executor()
  53. {
  54. // signal to all the worker thread that there will be no more submissions.
  55. close();
  56. }
  57. /**
  58. * \b Effects: close the \c inline_executor for submissions.
  59. * The loop will work until there is no more closures to run.
  60. */
  61. void close()
  62. {
  63. lock_guard<mutex> lk(mtx_);
  64. closed_ = true;
  65. }
  66. /**
  67. * \b Returns: whether the pool is closed for submissions.
  68. */
  69. bool closed(lock_guard<mutex>& )
  70. {
  71. return closed_;
  72. }
  73. bool closed()
  74. {
  75. lock_guard<mutex> lk(mtx_);
  76. return closed(lk);
  77. }
  78. /**
  79. * \b Requires: \c Closure is a model of \c Callable(void()) and a model of \c CopyConstructible/MoveConstructible.
  80. *
  81. * \b Effects: The specified \c closure will be scheduled for execution at some point in the future.
  82. * If invoked closure throws an exception the \c inline_executor will call \c std::terminate, as is the case with threads.
  83. *
  84. * \b Synchronization: completion of \c closure on a particular thread happens before destruction of thread's thread local variables.
  85. *
  86. * \b Throws: \c sync_queue_is_closed if the thread pool is closed.
  87. * Whatever exception that can be throw while storing the closure.
  88. */
  89. #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  90. template <typename Closure>
  91. void submit(Closure & closure)
  92. {
  93. {
  94. lock_guard<mutex> lk(mtx_);
  95. if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
  96. }
  97. try
  98. {
  99. closure();
  100. }
  101. catch (...)
  102. {
  103. std::terminate();
  104. return;
  105. }
  106. }
  107. #endif
  108. void submit(void (*closure)())
  109. {
  110. {
  111. lock_guard<mutex> lk(mtx_);
  112. if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
  113. }
  114. try
  115. {
  116. closure();
  117. }
  118. catch (...)
  119. {
  120. std::terminate();
  121. return;
  122. }
  123. }
  124. template <typename Closure>
  125. void submit(BOOST_THREAD_FWD_REF(Closure) closure)
  126. {
  127. {
  128. lock_guard<mutex> lk(mtx_);
  129. if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
  130. }
  131. try
  132. {
  133. closure();
  134. }
  135. catch (...)
  136. {
  137. std::terminate();
  138. return;
  139. }
  140. }
  141. /**
  142. * \b Requires: This must be called from an scheduled task.
  143. *
  144. * \b Effects: reschedule functions until pred()
  145. */
  146. template <typename Pred>
  147. bool reschedule_until(Pred const& )
  148. {
  149. return false;
  150. }
  151. };
  152. }
  153. using executors::inline_executor;
  154. }
  155. #include <boost/config/abi_suffix.hpp>
  156. #endif