diff --git a/asio/boostify.pl b/asio/boostify.pl index 6991e2f3..c117d8dd 100755 --- a/asio/boostify.pl +++ b/asio/boostify.pl @@ -579,6 +579,7 @@ sub copy_examples "src/examples/http/server", "src/examples/http/server2", "src/examples/http/server3", + "src/examples/invocation", "src/examples/iostreams", "src/examples/multicast", "src/examples/serialization", diff --git a/asio/src/Makefile.am b/asio/src/Makefile.am index 007a2662..a0aab4d2 100644 --- a/asio/src/Makefile.am +++ b/asio/src/Makefile.am @@ -62,6 +62,7 @@ noinst_PROGRAMS = \ examples/http/server/http_server \ examples/http/server2/http_server \ examples/http/server3/http_server \ + examples/invocation/prioritised_handlers \ examples/iostreams/daytime_client \ examples/iostreams/daytime_server \ examples/multicast/receiver \ @@ -268,6 +269,7 @@ else examples_http_server3_http_server_SOURCES += \ examples/http/server3/posix_main.cpp endif +examples_invocation_prioritised_handlers_SOURCES = examples/invocation/prioritised_handlers.cpp examples_iostreams_daytime_client_SOURCES = examples/iostreams/daytime_client.cpp examples_iostreams_daytime_server_SOURCES = examples/iostreams/daytime_server.cpp examples_multicast_receiver_SOURCES = examples/multicast/receiver.cpp diff --git a/asio/src/Makefile.bor b/asio/src/Makefile.bor index 2389f8c6..8f179903 100644 --- a/asio/src/Makefile.bor +++ b/asio/src/Makefile.bor @@ -70,6 +70,7 @@ EXAMPLE_EXES = \ examples\http\server\http_server.exe \ examples\http\server2\http_server.exe \ examples\http\server3\http_server.exe \ + examples\invocation\prioritised_handlers.exe \ examples\iostreams\daytime_client.exe \ examples\iostreams\daytime_server.exe \ examples\multicast\receiver.exe \ diff --git a/asio/src/Makefile.mgw b/asio/src/Makefile.mgw index 34faa6f5..906bfa7a 100644 --- a/asio/src/Makefile.mgw +++ b/asio/src/Makefile.mgw @@ -68,6 +68,7 @@ EXAMPLE_EXES = \ examples/echo/blocking_udp_echo_server.exe \ examples/http/client/async_client.exe \ examples/http/client/sync_client.exe \ + examples/invocation/prioritised_handlers.exe \ examples/iostreams/daytime_client.exe \ examples/iostreams/daytime_server.exe \ examples/multicast/receiver.exe \ diff --git a/asio/src/Makefile.msc b/asio/src/Makefile.msc index f25e391f..66f2779a 100644 --- a/asio/src/Makefile.msc +++ b/asio/src/Makefile.msc @@ -101,6 +101,7 @@ EXAMPLE_EXES = \ examples\http\server\http_server.exe \ examples\http\server2\http_server.exe \ examples\http\server3\http_server.exe \ + examples\invocation\prioritised_handlers.exe \ examples\iostreams\daytime_client.exe \ examples\iostreams\daytime_server.exe \ examples\multicast\receiver.exe \ @@ -158,6 +159,9 @@ check: $(UNIT_TEST_EXES) {examples\http\client}.cpp{examples\http\client}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< -link -opt:ref +{examples\invocation}.cpp{examples\invocation}.exe: + cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< -link -opt:ref + {examples\iostreams}.cpp{examples\iostreams}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< -link -opt:ref diff --git a/asio/src/examples/invocation/prioritised_handlers.cpp b/asio/src/examples/invocation/prioritised_handlers.cpp new file mode 100644 index 00000000..5cac7285 --- /dev/null +++ b/asio/src/examples/invocation/prioritised_handlers.cpp @@ -0,0 +1,147 @@ +// +// prioritised_handlers.cpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include "asio.hpp" +#include +#include +#include + +class handler_priority_queue +{ +public: + void add(int priority, boost::function function) + { + handlers_.push(queued_handler(priority, function)); + } + + void execute_all() + { + while (!handlers_.empty()) + { + queued_handler handler = handlers_.top(); + handler.execute(); + handlers_.pop(); + } + } + + // A generic wrapper class for handlers to allow the invocation to be hooked. + template + class wrapped_handler + { + public: + wrapped_handler(handler_priority_queue& q, int p, Handler h) + : queue_(q), priority_(p), handler_(h) + { + } + + void operator()() + { + handler_(); + } + + template + void operator()(Arg1 arg1) + { + handler_(arg1); + } + + template + void operator()(Arg1 arg1, Arg2 arg2) + { + handler_(arg1, arg2); + } + + //private: + handler_priority_queue& queue_; + int priority_; + Handler handler_; + }; + + template + wrapped_handler wrap(int priority, Handler handler) + { + return wrapped_handler(*this, priority, handler); + } + +private: + class queued_handler + { + public: + queued_handler(int p, boost::function f) + : priority_(p), function_(f) + { + } + + void execute() + { + function_(); + } + + friend bool operator<(const queued_handler& a, + const queued_handler& b) + { + return a.priority_ < b.priority_; + } + + private: + int priority_; + boost::function function_; + }; + + std::priority_queue handlers_; +}; + +// Custom invocation hook for wrapped handlers. +template +void asio_handler_invoke(Function f, + handler_priority_queue::wrapped_handler* h) +{ + h->queue_.add(h->priority_, f); +} + +//---------------------------------------------------------------------- + +void high_priority_handler() +{ + std::cout << "High priority handler\n"; +} + +void middle_priority_handler() +{ + std::cout << "Middle priority handler\n"; +} + +void low_priority_handler() +{ + std::cout << "Low priority handler\n"; +} + +int main() +{ + asio::io_service io_service; + + handler_priority_queue pri_queue; + + io_service.post(pri_queue.wrap(0, low_priority_handler)); + io_service.post(pri_queue.wrap(100, high_priority_handler)); + io_service.post(pri_queue.wrap(42, middle_priority_handler)); + + while (io_service.run_one()) + { + // The custom invocation hook adds the handlers to the priority queue + // rather than executing them from within the poll_one() call. + while (io_service.poll_one()) + ; + + pri_queue.execute_all(); + } + + return 0; +}