Add custom I/O executor support to basic_waitable_timer.
diff --git a/asio/include/asio/basic_waitable_timer.hpp b/asio/include/asio/basic_waitable_timer.hpp
index 56c02d7..3ff8772 100644
--- a/asio/include/asio/basic_waitable_timer.hpp
+++ b/asio/include/asio/basic_waitable_timer.hpp
@@ -23,6 +23,7 @@
 #include "asio/detail/io_object_impl.hpp"
 #include "asio/detail/throw_error.hpp"
 #include "asio/error.hpp"
+#include "asio/executor.hpp"
 #include "asio/wait_traits.hpp"
 
 #if defined(ASIO_HAS_MOVE)
@@ -38,7 +39,8 @@
 
 // Forward declaration with defaulted arguments.
 template <typename Clock,
-    typename WaitTraits = asio::wait_traits<Clock> >
+    typename WaitTraits = asio::wait_traits<Clock>,
+    typename Executor = asio::executor>
 class basic_waitable_timer;
 
 #endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
@@ -135,12 +137,12 @@
  * @li If a wait handler is cancelled, the asio::error_code passed to
  * it contains the value asio::error::operation_aborted.
  */
-template <typename Clock, typename WaitTraits>
+template <typename Clock, typename WaitTraits, typename Executor>
 class basic_waitable_timer
 {
 public:
   /// The type of the executor associated with the object.
-  typedef io_context::executor_type executor_type;
+  typedef Executor executor_type;
 
   /// The clock type.
   typedef Clock clock_type;
@@ -160,11 +162,28 @@
    * expires_at() or expires_after() functions must be called to set an expiry
    * time before the timer can be waited on.
    *
-   * @param io_context The io_context object that the timer will use to dispatch
+   * @param ex The executor object that the timer will use to dispatch
    * handlers for any asynchronous operations performed on the timer.
    */
-  explicit basic_waitable_timer(asio::io_context& io_context)
-    : impl_(io_context)
+  explicit basic_waitable_timer(const executor_type& ex)
+    : impl_(ex)
+  {
+  }
+
+  /// Constructor.
+  /**
+   * This constructor creates a timer without setting an expiry time. The
+   * expires_at() or expires_after() functions must be called to set an expiry
+   * time before the timer can be waited on.
+   *
+   * @param context The execution context object that the timer will use to
+   * dispatch handlers for any asynchronous operations performed on the timer.
+   */
+  template <typename ExecutionContext,
+      typename = typename enable_if<is_convertible<
+        ExecutionContext&, execution_context&>::value>::type>
+  explicit basic_waitable_timer(ExecutionContext& context)
+    : impl_(context)
   {
   }
 
@@ -172,15 +191,36 @@
   /**
    * This constructor creates a timer and sets the expiry time.
    *
-   * @param io_context The io_context object that the timer will use to dispatch
+   * @param ex The executor object that the timer will use to dispatch
    * handlers for any asynchronous operations performed on the timer.
    *
    * @param expiry_time The expiry time to be used for the timer, expressed
    * as an absolute time.
    */
-  basic_waitable_timer(asio::io_context& io_context,
+  basic_waitable_timer(const executor_type& ex, const time_point& expiry_time)
+    : impl_(ex)
+  {
+    asio::error_code ec;
+    impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_at");
+  }
+
+  /// Constructor to set a particular expiry time as an absolute time.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param context The execution context object that the timer will use to
+   * dispatch handlers for any asynchronous operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, expressed
+   * as an absolute time.
+   */
+  template <typename ExecutionContext,
+      typename = typename enable_if<is_convertible<
+        ExecutionContext&, execution_context&>::value>::type>
+  explicit basic_waitable_timer(ExecutionContext& context,
       const time_point& expiry_time)
-    : impl_(io_context)
+    : impl_(context)
   {
     asio::error_code ec;
     impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
@@ -191,15 +231,37 @@
   /**
    * This constructor creates a timer and sets the expiry time.
    *
-   * @param io_context The io_context object that the timer will use to dispatch
+   * @param ex The executor object that the timer will use to dispatch
    * handlers for any asynchronous operations performed on the timer.
    *
    * @param expiry_time The expiry time to be used for the timer, relative to
    * now.
    */
-  basic_waitable_timer(asio::io_context& io_context,
+  basic_waitable_timer(const executor_type& ex, const duration& expiry_time)
+    : impl_(ex)
+  {
+    asio::error_code ec;
+    impl_.get_service().expires_after(
+        impl_.get_implementation(), expiry_time, ec);
+    asio::detail::throw_error(ec, "expires_after");
+  }
+
+  /// Constructor to set a particular expiry time relative to now.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param ex The executor object that the timer will use to dispatch
+   * handlers for any asynchronous operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, relative to
+   * now.
+   */
+  template <typename ExecutionContext,
+      typename = typename enable_if<is_convertible<
+        ExecutionContext&, execution_context&>::value>::type>
+  explicit basic_waitable_timer(ExecutionContext& context,
       const duration& expiry_time)
-    : impl_(io_context)
+    : impl_(context)
   {
     asio::error_code ec;
     impl_.get_service().expires_after(
@@ -663,7 +725,7 @@
       void (asio::error_code)> init(handler);
 
     impl_.get_service().async_wait(impl_.get_implementation(),
-        init.completion_handler);
+        init.completion_handler, impl_.get_executor());
 
     return init.result.get();
   }
@@ -676,7 +738,8 @@
 
   detail::io_object_impl<
     detail::deadline_timer_service<
-      detail::chrono_time_traits<Clock, WaitTraits> > > impl_;
+      detail::chrono_time_traits<Clock, WaitTraits> >,
+    executor_type > impl_;
 };
 
 } // namespace asio
diff --git a/asio/include/asio/detail/deadline_timer_service.hpp b/asio/include/asio/detail/deadline_timer_service.hpp
index f58a6e0..6ea503d 100644
--- a/asio/include/asio/detail/deadline_timer_service.hpp
+++ b/asio/include/asio/detail/deadline_timer_service.hpp
@@ -43,7 +43,7 @@
 
 template <typename Time_Traits>
 class deadline_timer_service
-  : public service_base<deadline_timer_service<Time_Traits> >
+  : public execution_context_service_base<deadline_timer_service<Time_Traits> >
 {
 public:
   // The time type.
@@ -63,9 +63,9 @@
   };
 
   // Constructor.
-  deadline_timer_service(asio::io_context& io_context)
-    : service_base<deadline_timer_service<Time_Traits> >(io_context),
-      scheduler_(asio::use_service<timer_scheduler>(io_context))
+  deadline_timer_service(asio::execution_context& context)
+    : execution_context_service_base<deadline_timer_service<Time_Traits> >(context),
+      scheduler_(asio::use_service<timer_scheduler>(context))
   {
     scheduler_.init_task();
     scheduler_.add_timer_queue(timer_queue_);
@@ -225,14 +225,14 @@
   }
 
   // Start an asynchronous wait on the timer.
-  template <typename Handler>
-  void async_wait(implementation_type& impl, Handler& handler)
+  template <typename Handler, typename IoExecutor>
+  void async_wait(implementation_type& impl, Handler& handler, const IoExecutor& io_ex)
   {
     // Allocate and construct an operation to wrap the handler.
-    typedef wait_handler<Handler> op;
+    typedef wait_handler<Handler, IoExecutor> op;
     typename op::ptr p = { asio::detail::addressof(handler),
       op::ptr::allocate(handler), 0 };
-    p.p = new (p.v) op(handler);
+    p.p = new (p.v) op(handler, io_ex);
 
     impl.might_have_pending_waits = true;
 
diff --git a/asio/include/asio/detail/handler_work.hpp b/asio/include/asio/detail/handler_work.hpp
index cce5c4b..3b62d0d 100644
--- a/asio/include/asio/detail/handler_work.hpp
+++ b/asio/include/asio/detail/handler_work.hpp
@@ -27,24 +27,41 @@
 // A helper class template to allow completion handlers to be dispatched
 // through either the new executors framework or the old invocaton hook. The
 // primary template uses the new executors framework.
-template <typename Handler, typename Executor
-    = typename associated_executor<Handler>::type>
+template <typename Handler,
+    typename IoExecutor = system_executor, typename HandlerExecutor
+      = typename associated_executor<Handler, IoExecutor>::type>
 class handler_work
 {
 public:
   explicit handler_work(Handler& handler) ASIO_NOEXCEPT
-    : executor_(associated_executor<Handler>::get(handler))
+    : io_executor_(),
+      executor_(asio::get_associated_executor(handler, io_executor_))
+  {
+  }
+
+  handler_work(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT
+    : io_executor_(io_ex),
+      executor_(asio::get_associated_executor(handler, io_executor_))
   {
   }
 
   static void start(Handler& handler) ASIO_NOEXCEPT
   {
-    Executor ex(associated_executor<Handler>::get(handler));
+    HandlerExecutor ex(asio::get_associated_executor(handler));
     ex.on_work_started();
   }
 
+  static void start(Handler& handler,
+      const IoExecutor& io_ex) ASIO_NOEXCEPT
+  {
+    HandlerExecutor ex(asio::get_associated_executor(handler, io_ex));
+    ex.on_work_started();
+    io_ex.on_work_started();
+  }
+
   ~handler_work()
   {
+    io_executor_.on_work_finished();
     executor_.on_work_finished();
   }
 
@@ -52,7 +69,7 @@
   void complete(Function& function, Handler& handler)
   {
     executor_.dispatch(ASIO_MOVE_CAST(Function)(function),
-        associated_allocator<Handler>::get(handler));
+        asio::get_associated_allocator(handler));
   }
 
 private:
@@ -60,7 +77,8 @@
   handler_work(const handler_work&);
   handler_work& operator=(const handler_work&);
 
-  typename associated_executor<Handler>::type executor_;
+  IoExecutor io_executor_;
+  HandlerExecutor executor_;
 };
 
 // This specialisation dispatches a handler through the old invocation hook.
@@ -68,7 +86,7 @@
 // system_executor will dispatch through the hook anyway. However, by doing
 // this we avoid an extra copy of the handler.
 template <typename Handler>
-class handler_work<Handler, system_executor>
+class handler_work<Handler, system_executor, system_executor>
 {
 public:
   explicit handler_work(Handler&) ASIO_NOEXCEPT {}
diff --git a/asio/include/asio/detail/impl/scheduler.ipp b/asio/include/asio/detail/impl/scheduler.ipp
index 35bc678..7a51c07 100644
--- a/asio/include/asio/detail/impl/scheduler.ipp
+++ b/asio/include/asio/detail/impl/scheduler.ipp
@@ -23,6 +23,7 @@
 #include "asio/detail/reactor.hpp"
 #include "asio/detail/scheduler.hpp"
 #include "asio/detail/scheduler_thread_info.hpp"
+#include "asio/detail/signal_blocker.hpp"
 
 #include "asio/detail/push_options.hpp"
 
@@ -84,8 +85,8 @@
   thread_info* this_thread_;
 };
 
-scheduler::scheduler(
-    asio::execution_context& ctx, int concurrency_hint)
+scheduler::scheduler(asio::execution_context& ctx,
+    int concurrency_hint, bool own_thread)
   : asio::detail::execution_context_service_base<scheduler>(ctx),
     one_thread_(concurrency_hint == 1
         || !ASIO_CONCURRENCY_HINT_IS_LOCKING(
@@ -99,17 +100,44 @@
     outstanding_work_(0),
     stopped_(false),
     shutdown_(false),
-    concurrency_hint_(concurrency_hint)
+    concurrency_hint_(concurrency_hint),
+    thread_(0)
 {
   ASIO_HANDLER_TRACKING_INIT;
+
+  if (own_thread)
+  {
+    ++outstanding_work_;
+    asio::detail::signal_blocker sb;
+    thread_ = new asio::detail::thread([this] { asio::error_code ec; run(ec); });
+  }
+}
+
+scheduler::~scheduler()
+{
+  if (thread_)
+  {
+    thread_->join();
+    delete thread_;
+  }
 }
 
 void scheduler::shutdown()
 {
   mutex::scoped_lock lock(mutex_);
   shutdown_ = true;
+  if (thread_)
+    stop_all_threads(lock);
   lock.unlock();
 
+  // Join thread to ensure task operation is returned to queue.
+  if (thread_)
+  {
+    thread_->join();
+    delete thread_;
+    thread_ = 0;
+  }
+
   // Destroy handler objects.
   while (!op_queue_.empty())
   {
diff --git a/asio/include/asio/detail/io_object_impl.hpp b/asio/include/asio/detail/io_object_impl.hpp
index 524392e..3705476 100644
--- a/asio/include/asio/detail/io_object_impl.hpp
+++ b/asio/include/asio/detail/io_object_impl.hpp
@@ -15,15 +15,19 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
+#include <new>
 #include "asio/detail/config.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/io_context.hpp"
+#include "asio/is_executor.hpp"
 
 #include "asio/detail/push_options.hpp"
 
 namespace asio {
 namespace detail {
 
-template <typename IoObjectService>
+template <typename IoObjectService,
+    typename Executor = io_context::executor_type>
 class io_object_impl
 {
 public:
@@ -34,11 +38,23 @@
   typedef typename service_type::implementation_type implementation_type;
 
   // The type of the executor associated with the object.
-  typedef asio::io_context::executor_type executor_type;
+  typedef Executor executor_type;
 
-  // Construct an I/O object.
-  explicit io_object_impl(asio::io_context& io_context)
-    : service_(&asio::use_service<IoObjectService>(io_context))
+  // Construct an I/O object using an executor.
+  explicit io_object_impl(const executor_type& ex)
+    : executor_(ex),
+      service_(&asio::use_service<IoObjectService>(ex.context()))
+  {
+    service_->construct(implementation_);
+  }
+
+  // Construct an I/O object using an execution context.
+  template <typename ExecutionContext>
+  explicit io_object_impl(ExecutionContext& context,
+      typename enable_if<is_convertible<
+        ExecutionContext&, execution_context&>::value>::type* = 0)
+    : executor_(context.get_executor()),
+      service_(&asio::use_service<IoObjectService>(context))
   {
     service_->construct(implementation_);
   }
@@ -46,7 +62,8 @@
 #if defined(ASIO_HAS_MOVE)
   // Move-construct an I/O object.
   io_object_impl(io_object_impl&& other)
-    : service_(&other.get_service())
+    : executor_(other.get_executor()),
+      service_(&other.get_service())
   {
     service_->move_construct(implementation_, other.implementation_);
   }
@@ -55,8 +72,9 @@
   template <typename IoObjectService1>
   io_object_impl(IoObjectService1& other_service,
       typename IoObjectService1::implementation_type& other_implementation)
-    : service_(&asio::use_service<IoObjectService>(
-          other_service.get_io_context()))
+    : executor_(other_service.get_io_context().get_executor()), // TODO
+      service_(&asio::use_service<IoObjectService>(
+            other_service.get_io_context()))
   {
     service_->converting_move_construct(implementation_,
         other_service, other_implementation);
@@ -73,9 +91,14 @@
   // Move-assign an I/O object.
   io_object_impl& operator=(io_object_impl&& other)
   {
-    service_->move_assign(implementation_,
-        *other.service_, other.implementation_);
-    service_ = other.service_;
+    if (this != &other)
+    {
+      service_->move_assign(implementation_,
+          *other.service_, other.implementation_);
+      executor_.~executor_type();
+      new (&executor_) executor_type(std::move(other.executor_));
+      service_ = other.service_;
+    }
     return *this;
   }
 #endif // defined(ASIO_HAS_MOVE)
@@ -97,7 +120,7 @@
   // Get the executor associated with the object.
   executor_type get_executor() ASIO_NOEXCEPT
   {
-    return service_->get_io_context().get_executor();
+    return executor_;
   }
 
   // Get the service associated with the I/O object.
@@ -129,6 +152,9 @@
   io_object_impl(const io_object_impl&);
   io_object_impl& operator=(const io_object_impl&);
 
+  // The associated executor.
+  executor_type executor_;
+
   // The service associated with the I/O object.
   service_type* service_;
 
diff --git a/asio/include/asio/detail/scheduler.hpp b/asio/include/asio/detail/scheduler.hpp
index 10c29b7..eada5a8 100644
--- a/asio/include/asio/detail/scheduler.hpp
+++ b/asio/include/asio/detail/scheduler.hpp
@@ -25,6 +25,7 @@
 #include "asio/detail/op_queue.hpp"
 #include "asio/detail/reactor_fwd.hpp"
 #include "asio/detail/scheduler_operation.hpp"
+#include "asio/detail/thread.hpp"
 #include "asio/detail/thread_context.hpp"
 
 #include "asio/detail/push_options.hpp"
@@ -44,7 +45,10 @@
   // Constructor. Specifies the number of concurrent threads that are likely to
   // run the scheduler. If set to 1 certain optimisation are performed.
   ASIO_DECL scheduler(asio::execution_context& ctx,
-      int concurrency_hint = 0);
+      int concurrency_hint = 0, bool own_thread = true);
+
+  // Destructor.
+  ASIO_DECL ~scheduler();
 
   // Destroy all user-defined handler objects owned by the service.
   ASIO_DECL void shutdown();
@@ -199,6 +203,9 @@
 
   // The concurrency hint used to initialise the scheduler.
   const int concurrency_hint_;
+
+  // The thread that is running the scheduler.
+  asio::detail::thread* thread_;
 };
 
 } // namespace detail
diff --git a/asio/include/asio/detail/thread_group.hpp b/asio/include/asio/detail/thread_group.hpp
index 1e400b0..f39f8e5 100644
--- a/asio/include/asio/detail/thread_group.hpp
+++ b/asio/include/asio/detail/thread_group.hpp
@@ -64,6 +64,12 @@
     }
   }
 
+  // Test whether the group is empty.
+  bool empty() const
+  {
+    return first_ == 0;
+  }
+
 private:
   // Structure used to track a single thread in the group.
   struct item
diff --git a/asio/include/asio/detail/wait_handler.hpp b/asio/include/asio/detail/wait_handler.hpp
index bd3dc24..5053952 100644
--- a/asio/include/asio/detail/wait_handler.hpp
+++ b/asio/include/asio/detail/wait_handler.hpp
@@ -28,17 +28,18 @@
 namespace asio {
 namespace detail {
 
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
 class wait_handler : public wait_op
 {
 public:
   ASIO_DEFINE_HANDLER_PTR(wait_handler);
 
-  wait_handler(Handler& h)
+  wait_handler(Handler& h, const IoExecutor& ex)
     : wait_op(&wait_handler::do_complete),
-      handler_(ASIO_MOVE_CAST(Handler)(h))
+      handler_(ASIO_MOVE_CAST(Handler)(h)),
+      io_executor_(ex)
   {
-    handler_work<Handler>::start(handler_);
+    handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
   }
 
   static void do_complete(void* owner, operation* base,
@@ -48,7 +49,7 @@
     // Take ownership of the handler object.
     wait_handler* h(static_cast<wait_handler*>(base));
     ptr p = { asio::detail::addressof(h->handler_), h, h };
-    handler_work<Handler> w(h->handler_);
+    handler_work<Handler, IoExecutor> w(h->handler_, h->io_executor_);
 
     ASIO_HANDLER_COMPLETION((*h));
 
@@ -75,6 +76,7 @@
 
 private:
   Handler handler_;
+  IoExecutor io_executor_;
 };
 
 } // namespace detail
diff --git a/asio/include/asio/execution_context.hpp b/asio/include/asio/execution_context.hpp
index 1476d19..49c019c 100644
--- a/asio/include/asio/execution_context.hpp
+++ b/asio/include/asio/execution_context.hpp
@@ -109,13 +109,14 @@
   class id;
   class service;
 
-protected:
+public:
   /// Constructor.
   ASIO_DECL execution_context();
 
   /// Destructor.
   ASIO_DECL ~execution_context();
 
+protected:
   /// Shuts down all services in the context.
   /**
    * This function is implemented as follows:
diff --git a/asio/include/asio/impl/io_context.ipp b/asio/include/asio/impl/io_context.ipp
index 7eb467d..9653ac8 100644
--- a/asio/include/asio/impl/io_context.ipp
+++ b/asio/include/asio/impl/io_context.ipp
@@ -34,13 +34,13 @@
 namespace asio {
 
 io_context::io_context()
-  : impl_(add_impl(new impl_type(*this, ASIO_CONCURRENCY_HINT_DEFAULT)))
+  : impl_(add_impl(new impl_type(*this, ASIO_CONCURRENCY_HINT_DEFAULT, false)))
 {
 }
 
 io_context::io_context(int concurrency_hint)
   : impl_(add_impl(new impl_type(*this, concurrency_hint == 1
-          ? ASIO_CONCURRENCY_HINT_1 : concurrency_hint)))
+          ? ASIO_CONCURRENCY_HINT_1 : concurrency_hint, false)))
 {
 }
 
diff --git a/asio/include/asio/impl/system_context.ipp b/asio/include/asio/impl/system_context.ipp
index 8ad5e41..ef36681 100644
--- a/asio/include/asio/impl/system_context.ipp
+++ b/asio/include/asio/impl/system_context.ipp
@@ -34,7 +34,7 @@
 };
 
 system_context::system_context()
-  : scheduler_(use_service<detail::scheduler>(*this))
+  : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false)))
 {
   scheduler_.work_started();
 
@@ -66,6 +66,13 @@
   threads_.join();
 }
 
+detail::scheduler& system_context::add_scheduler(detail::scheduler* s)
+{
+  detail::scoped_ptr<detail::scheduler> scoped_impl(s);
+  asio::add_service<detail::scheduler>(*this, scoped_impl.get());
+  return *scoped_impl.release();
+}
+
 } // namespace asio
 
 #include "asio/detail/pop_options.hpp"
diff --git a/asio/include/asio/impl/thread_pool.ipp b/asio/include/asio/impl/thread_pool.ipp
index 89583c1..63a35a7 100644
--- a/asio/include/asio/impl/thread_pool.ipp
+++ b/asio/include/asio/impl/thread_pool.ipp
@@ -34,7 +34,7 @@
 };
 
 thread_pool::thread_pool()
-  : scheduler_(use_service<detail::scheduler>(*this))
+  : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false)))
 {
   scheduler_.work_started();
 
@@ -44,7 +44,8 @@
 }
 
 thread_pool::thread_pool(std::size_t num_threads)
-  : scheduler_(use_service<detail::scheduler>(*this))
+  : scheduler_(add_scheduler(new detail::scheduler(*this, num_threads == 1
+          ? ASIO_CONCURRENCY_HINT_1 : num_threads, false)))
 {
   scheduler_.work_started();
 
@@ -65,8 +66,18 @@
 
 void thread_pool::join()
 {
-  scheduler_.work_finished();
-  threads_.join();
+  if (!threads_.empty())
+  {
+    scheduler_.work_finished();
+    threads_.join();
+  }
+}
+
+detail::scheduler& thread_pool::add_scheduler(detail::scheduler* s)
+{
+  detail::scoped_ptr<detail::scheduler> scoped_impl(s);
+  asio::add_service<detail::scheduler>(*this, scoped_impl.get());
+  return *scoped_impl.release();
 }
 
 } // namespace asio
diff --git a/asio/include/asio/system_context.hpp b/asio/include/asio/system_context.hpp
index ccd1113..134c9e9 100644
--- a/asio/include/asio/system_context.hpp
+++ b/asio/include/asio/system_context.hpp
@@ -59,6 +59,9 @@
 
   struct thread_function;
 
+  // Helper function to create the underlying scheduler.
+  ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s);
+
   // The underlying scheduler.
   detail::scheduler& scheduler_;
 
diff --git a/asio/include/asio/thread_pool.hpp b/asio/include/asio/thread_pool.hpp
index f22f18d..2c098f2 100644
--- a/asio/include/asio/thread_pool.hpp
+++ b/asio/include/asio/thread_pool.hpp
@@ -100,6 +100,9 @@
   friend class executor_type;
   struct thread_function;
 
+  // Helper function to create the underlying scheduler.
+  ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s);
+
   // The underlying scheduler.
   detail::scheduler& scheduler_;
 
diff --git a/asio/include/asio/ts/netfwd.hpp b/asio/include/asio/ts/netfwd.hpp
index 80d7b60..1feb8e0 100644
--- a/asio/include/asio/ts/netfwd.hpp
+++ b/asio/include/asio/ts/netfwd.hpp
@@ -62,7 +62,8 @@
 #define ASIO_BASIC_WAITABLE_TIMER_FWD_DECL
 
 template <typename Clock,
-    typename WaitTraits = asio::wait_traits<Clock> >
+    typename WaitTraits = wait_traits<Clock>,
+    typename Executor = executor>
 class basic_waitable_timer;
 
 #endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
diff --git a/asio/src/examples/cpp11/invocation/prioritised_handlers.cpp b/asio/src/examples/cpp11/invocation/prioritised_handlers.cpp
index 1619875..81490c7 100644
--- a/asio/src/examples/cpp11/invocation/prioritised_handlers.cpp
+++ b/asio/src/examples/cpp11/invocation/prioritised_handlers.cpp
@@ -15,7 +15,7 @@
 
 using asio::ip::tcp;
 
-class handler_priority_queue : asio::execution_context
+class handler_priority_queue : public asio::execution_context
 {
 public:
   template <typename Function>