Files
concurrency-in-action/source/listing_c.4.cpp
2018-10-18 00:40:34 -05:00

54 lines
1.1 KiB
C++

namespace messaging {
class close_queue {
};
class dispatcher {
queue* q;
bool chained;
dispatcher(dispatcher const&) = delete;
dispatcher& operator=(dispatcher const&) = delete;
template <typename Dispatcher, typename Msg, typename Func>
friend class TemplateDispatcher;
void wait_and_dispatch()
{
for (;;) {
auto msg = q->wait_and_pop();
dispatch(msg);
}
}
bool dispatch(std::shared_ptr<message_base> const& msg)
{
if (dynamic_cast<wrapped_message<close_queue>*>(msg.get())) {
throw close_queue();
}
return false;
}
public:
dispatcher(dispatcher&& other) : q(other.q), chained(other.chained)
{
other.chained = true;
}
explicit dispatcher(queue* q_) : q(q_), chained(false) {}
template <typename Message, typename Func>
TemplateDispatcher<dispatcher, Message, Func> handle(Func&& f)
{
return TemplateDispatcher<dispatcher, Message, Func>(
q, this, std::forward<Func>(f));
}
~dispatcher() noexcept(false)
{
if (!chained) {
wait_and_dispatch();
}
}
};
} // namespace messaging