1 #include <boost/asio/dispatch.hpp>
2 #include <boost/asio/execution_context.hpp>
3 #include <condition_variable>
9 using boost::asio::dispatch
;
10 using boost::asio::execution_context
;
11 namespace execution
= boost::asio::execution
;
13 class priority_scheduler
: public execution_context
16 // A class that satisfies the Executor requirements.
20 executor_type(priority_scheduler
& ctx
, int pri
) noexcept
21 : context_(ctx
), priority_(pri
)
25 priority_scheduler
& query(execution::context_t
) const noexcept
31 void execute(Func f
) const
33 auto p(std::make_shared
<item
<Func
>>(priority_
, std::move(f
)));
34 std::lock_guard
<std::mutex
> lock(context_
.mutex_
);
35 context_
.queue_
.push(p
);
36 context_
.condition_
.notify_one();
39 friend bool operator==(const executor_type
& a
,
40 const executor_type
& b
) noexcept
42 return &a
.context_
== &b
.context_
;
45 friend bool operator!=(const executor_type
& a
,
46 const executor_type
& b
) noexcept
48 return &a
.context_
!= &b
.context_
;
52 priority_scheduler
& context_
;
56 ~priority_scheduler() noexcept
62 executor_type
get_executor(int pri
= 0) noexcept
64 return executor_type(*const_cast<priority_scheduler
*>(this), pri
);
69 std::unique_lock
<std::mutex
> lock(mutex_
);
72 condition_
.wait(lock
, [&]{ return stopped_
|| !queue_
.empty(); });
85 std::lock_guard
<std::mutex
> lock(mutex_
);
87 condition_
.notify_all();
94 void (*execute_
)(std::shared_ptr
<item_base
>&);
98 struct item
: item_base
100 item(int pri
, Func f
) : function_(std::move(f
))
103 execute_
= [](std::shared_ptr
<item_base
>& p
)
105 Func
tmp(std::move(static_cast<item
*>(p
.get())->function_
));
117 const std::shared_ptr
<item_base
>& a
,
118 const std::shared_ptr
<item_base
>& b
)
120 return a
->priority_
< b
->priority_
;
125 std::condition_variable condition_
;
127 std::shared_ptr
<item_base
>,
128 std::vector
<std::shared_ptr
<item_base
>>,
130 bool stopped_
= false;
135 priority_scheduler sched
;
136 auto low
= sched
.get_executor(0);
137 auto med
= sched
.get_executor(1);
138 auto high
= sched
.get_executor(2);
139 dispatch(low
, []{ std::cout
<< "1\n"; });
140 dispatch(low
, []{ std::cout
<< "11\n"; });
141 dispatch(med
, []{ std::cout
<< "2\n"; });
142 dispatch(med
, []{ std::cout
<< "22\n"; });
143 dispatch(high
, []{ std::cout
<< "3\n"; });
144 dispatch(high
, []{ std::cout
<< "33\n"; });
145 dispatch(high
, []{ std::cout
<< "333\n"; });
146 dispatch(sched
.get_executor(-1), [&]{ sched
.stop(); });