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