1// <experimental/executor> -*- C++ -*-
2
3// Copyright (C) 2015-2019 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file experimental/executor
26 *  This is a TS C++ Library header.
27 */
28
29#ifndef _GLIBCXX_EXPERIMENTAL_EXECUTOR
30#define _GLIBCXX_EXPERIMENTAL_EXECUTOR 1
31
32#pragma GCC system_header
33
34#if __cplusplus >= 201402L
35
36#include <algorithm>
37#include <condition_variable>
38#include <functional>
39#include <future>
40#include <list>
41#include <queue>
42#include <thread>
43#include <tuple>
44#include <unordered_map>
45#include <utility>
46#include <experimental/netfwd>
47#include <bits/unique_ptr.h>
48#include <experimental/bits/net.h>
49
50namespace std _GLIBCXX_VISIBILITY(default)
51{
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
53namespace experimental
54{
55namespace net
56{
57inline namespace v1
58{
59
60  /**
61   * @ingroup networking
62   * @{
63   */
64
65  /// Customization point for asynchronous operations.
66  template<typename _CompletionToken, typename _Signature, typename = void>
67    class async_result;
68
69  /// Convenience utility to help implement asynchronous operations.
70  template<typename _CompletionToken, typename _Signature>
71    class async_completion;
72
73  template<typename _Tp, typename _ProtoAlloc, typename = __void_t<>>
74    struct __associated_allocator_impl
75    {
76      using type = _ProtoAlloc;
77
78      static type
79      _S_get(const _Tp&, const _ProtoAlloc& __a) noexcept { return __a; }
80    };
81
82  template<typename _Tp, typename _ProtoAlloc>
83    struct __associated_allocator_impl<_Tp, _ProtoAlloc,
84				       __void_t<typename _Tp::allocator_type>>
85    {
86      using type = typename _Tp::allocator_type;
87
88      static type
89      _S_get(const _Tp& __t, const _ProtoAlloc&) noexcept
90      { return __t.get_allocator(); }
91    };
92
93  /// Helper to associate an allocator with a type.
94  template<typename _Tp, typename _ProtoAllocator = allocator<void>>
95    struct associated_allocator
96    : __associated_allocator_impl<_Tp, _ProtoAllocator>
97    {
98      static auto
99      get(const _Tp& __t,
100	  const _ProtoAllocator& __a = _ProtoAllocator()) noexcept
101      {
102	using _Impl = __associated_allocator_impl<_Tp, _ProtoAllocator>;
103	return _Impl::_S_get(__t, __a);
104      }
105    };
106
107  /// Alias template for associated_allocator.
108  template<typename _Tp, typename _ProtoAllocator = allocator<void>>
109    using associated_allocator_t
110      = typename associated_allocator<_Tp, _ProtoAllocator>::type;
111
112  // get_associated_allocator:
113
114  template<typename _Tp>
115    inline associated_allocator_t<_Tp>
116    get_associated_allocator(const _Tp& __t) noexcept
117    { return associated_allocator<_Tp>::get(__t); }
118
119  template<typename _Tp, typename _ProtoAllocator>
120    inline associated_allocator_t<_Tp, _ProtoAllocator>
121    get_associated_allocator(const _Tp& __t,
122			     const _ProtoAllocator& __a) noexcept
123    { return associated_allocator<_Tp, _ProtoAllocator>::get(__t, __a); }
124
125  enum class fork_event { prepare, parent, child };
126
127  /// An extensible, type-safe, polymorphic set of services.
128  class execution_context;
129
130  class service_already_exists : public logic_error
131  {
132  public:
133    // _GLIBCXX_RESOLVE_LIB_DEFECTS
134    // 3414. service_already_exists has no usable constructors
135    service_already_exists() : logic_error("service already exists") { }
136  };
137
138  template<typename _Tp> struct is_executor;
139
140  struct executor_arg_t { };
141
142  constexpr executor_arg_t executor_arg = executor_arg_t();
143
144  /// Trait for determining whether to construct an object with an executor.
145  template<typename _Tp, typename _Executor> struct uses_executor;
146
147  template<typename _Tp, typename _Executor, typename = __void_t<>>
148    struct __associated_executor_impl
149    {
150      using type = _Executor;
151
152      static type
153      _S_get(const _Tp&, const _Executor& __e) noexcept { return __e; }
154    };
155
156  template<typename _Tp, typename _Executor>
157    struct __associated_executor_impl<_Tp, _Executor,
158				       __void_t<typename _Tp::executor_type>>
159    {
160      using type = typename _Tp::executor_type;
161
162      static type
163      _S_get(const _Tp& __t, const _Executor&) noexcept
164      { return __t.get_executor(); }
165    };
166
167  /// Helper to associate an executor with a type.
168  template<typename _Tp, typename _Executor = system_executor>
169    struct associated_executor
170    : __associated_executor_impl<_Tp, _Executor>
171    {
172      static auto
173      get(const _Tp& __t, const _Executor& __e = _Executor()) noexcept
174      { return __associated_executor_impl<_Tp, _Executor>::_S_get(__t, __e); }
175    };
176
177
178  template<typename _Tp, typename _Executor = system_executor>
179    using associated_executor_t
180      = typename associated_executor<_Tp, _Executor>::type;
181
182  template<typename _ExecutionContext>
183    using __is_exec_context
184      = is_convertible<_ExecutionContext&, execution_context&>;
185
186  template<typename _Tp>
187    using __executor_t = typename _Tp::executor_type;
188
189  // get_associated_executor:
190
191  template<typename _Tp>
192    inline associated_executor_t<_Tp>
193    get_associated_executor(const _Tp& __t) noexcept
194    { return associated_executor<_Tp>::get(__t); }
195
196  template<typename _Tp, typename _Executor>
197    inline
198    enable_if_t<is_executor<_Executor>::value,
199		associated_executor_t<_Tp, _Executor>>
200    get_associated_executor(const _Tp& __t, const _Executor& __ex)
201    { return associated_executor<_Tp, _Executor>::get(__t, __ex); }
202
203  template<typename _Tp, typename _ExecutionContext>
204    inline
205    enable_if_t<__is_exec_context<_ExecutionContext>::value,
206		associated_executor_t<_Tp, __executor_t<_ExecutionContext>>>
207    get_associated_executor(const _Tp& __t, _ExecutionContext& __ctx) noexcept
208    { return net::get_associated_executor(__t, __ctx.get_executor()); }
209
210
211  /// Helper to bind an executor to an object or function.
212  template<typename _Tp, typename _Executor>
213    class executor_binder;
214
215  template<typename _Tp, typename _Executor, typename _Signature>
216    class async_result<executor_binder<_Tp, _Executor>, _Signature>;
217
218  template<typename _Tp, typename _Executor, typename _ProtoAllocator>
219    struct associated_allocator<executor_binder<_Tp, _Executor>,
220				_ProtoAllocator>;
221
222  template<typename _Tp, typename _Executor, typename _Executor1>
223    struct associated_executor<executor_binder<_Tp, _Executor>, _Executor1>;
224
225  // bind_executor:
226
227  template<typename _Executor, typename _Tp>
228    inline
229    enable_if_t<is_executor<_Executor>::value,
230		executor_binder<decay_t<_Tp>, _Executor>>
231    bind_executor(const _Executor& __ex, _Tp&& __t)
232    { return { std::forward<_Tp>(__t), __ex }; }
233
234  template<typename _ExecutionContext, typename _Tp>
235    inline
236    enable_if_t<__is_exec_context<_ExecutionContext>::value,
237		executor_binder<decay_t<_Tp>, __executor_t<_ExecutionContext>>>
238    bind_executor(_ExecutionContext& __ctx, _Tp&& __t)
239    { return { __ctx.get_executor(), forward<_Tp>(__t) }; }
240
241
242  /// A scope-guard type to record when work is started and finished.
243  template<typename _Executor>
244    class executor_work_guard;
245
246  // make_work_guard:
247
248  template<typename _Executor>
249    inline
250    enable_if_t<is_executor<_Executor>::value, executor_work_guard<_Executor>>
251    make_work_guard(const _Executor& __ex)
252    { return executor_work_guard<_Executor>(__ex); }
253
254  template<typename _ExecutionContext>
255    inline
256    enable_if_t<__is_exec_context<_ExecutionContext>::value,
257		executor_work_guard<__executor_t<_ExecutionContext>>>
258    make_work_guard(_ExecutionContext& __ctx)
259    { return net::make_work_guard(__ctx.get_executor()); }
260
261  template<typename _Tp>
262    inline
263    enable_if_t<__not_<__or_<is_executor<_Tp>, __is_exec_context<_Tp>>>::value,
264		executor_work_guard<associated_executor_t<_Tp>>>
265    make_work_guard(const _Tp& __t)
266    { return net::get_associated_executor(__t); }
267
268  template<typename _Tp, typename _Up>
269    auto
270    make_work_guard(const _Tp& __t, _Up&& __u)
271    -> decltype(net::make_work_guard(
272	  net::get_associated_executor(__t, forward<_Up>(__u))))
273    {
274      return net::make_work_guard(
275	  net::get_associated_executor(__t, forward<_Up>(__u)));
276    }
277
278  /// Allows function objects to execute on any thread.
279  class system_executor;
280
281  /// The execution context associated with system_executor objects.
282  class system_context;
283
284  inline bool
285  operator==(const system_executor&, const system_executor&) { return true; }
286
287  inline bool
288  operator!=(const system_executor&, const system_executor&) { return false; }
289
290  /// Exception thrown by empty executors.
291  class bad_executor;
292
293  /// Polymorphic wrapper for types satisfying the Executor requirements.
294  class executor;
295
296  bool
297  operator==(const executor&, const executor&) noexcept;
298
299  bool
300  operator==(const executor&, nullptr_t) noexcept;
301
302  bool
303  operator==(nullptr_t, const executor&) noexcept;
304
305  bool
306  operator!=(const executor&, const executor&) noexcept;
307
308  bool
309  operator!=(const executor&, nullptr_t) noexcept;
310
311  bool
312  operator!=(nullptr_t, const executor&) noexcept;
313
314  void swap(executor&, executor&) noexcept;
315
316  // dispatch:
317
318  template<typename _CompletionToken>
319    __deduced_t<_CompletionToken, void()>
320    dispatch(_CompletionToken&& __token);
321
322  template<typename _Executor, typename _CompletionToken>
323    __deduced_t<_CompletionToken, void()>
324    dispatch(const _Executor& __ex, _CompletionToken&& __token);
325
326  template<typename _ExecutionContext, typename _CompletionToken>
327    __deduced_t<_CompletionToken, void()>
328    dispatch(_ExecutionContext& __ctx, _CompletionToken&& __token);
329
330  // post:
331
332  template<typename _CompletionToken>
333    __deduced_t<_CompletionToken, void()>
334    post(_CompletionToken&& __token);
335  template<typename _Executor, typename _CompletionToken>
336    enable_if_t<is_executor<_Executor>::value,
337		__deduced_t<_CompletionToken, void()>>
338    post(const _Executor& __ex, _CompletionToken&& __token);
339  template<typename _ExecutionContext, typename _CompletionToken>
340    enable_if_t<__is_exec_context<_ExecutionContext>::value,
341		__deduced_t<_CompletionToken, void()>>
342    post(_ExecutionContext& __ctx, _CompletionToken&& __token);
343
344  // defer:
345
346  template<typename _CompletionToken>
347    __deduced_t<_CompletionToken, void()>
348    defer(_CompletionToken&& __token);
349  template<typename _Executor, typename _CompletionToken>
350    __deduced_t<_CompletionToken, void()>
351    defer(const _Executor& __ex, _CompletionToken&& __token);
352  template<typename _ExecutionContext, typename _CompletionToken>
353    __deduced_t<_CompletionToken, void()>
354    defer(_ExecutionContext& __ctx, _CompletionToken&& __token);
355
356  template<typename _Executor>
357    class strand;
358
359  template<typename _Executor>
360    bool
361    operator==(const strand<_Executor>& __a, const strand<_Executor>& __b);
362
363  template<typename _Executor>
364    bool
365    operator!=(const strand<_Executor>& __a, const strand<_Executor>& __b)
366    { return !(__a == __b); }
367
368  template<typename _CompletionToken, typename _Signature, typename>
369    class async_result
370    {
371    public:
372      typedef _CompletionToken completion_handler_type;
373      typedef void return_type;
374
375      explicit async_result(completion_handler_type&) {}
376      async_result(const async_result&) = delete;
377      async_result& operator=(const async_result&) = delete;
378
379      return_type get() {}
380    };
381
382  template<typename _CompletionToken, typename _Signature>
383    class async_completion
384    {
385      using __result_type
386	= async_result<decay_t<_CompletionToken>, _Signature>;
387
388    public:
389      using completion_handler_type
390	= typename __result_type::completion_handler_type;
391
392    private:
393      using __handler_type = conditional_t<
394	is_same<_CompletionToken, completion_handler_type>::value,
395	completion_handler_type&,
396	completion_handler_type>;
397
398    public:
399      explicit
400      async_completion(_CompletionToken& __t)
401      : completion_handler(std::forward<__handler_type>(__t)),
402	result(completion_handler)
403      { }
404
405      async_completion(const async_completion&) = delete;
406      async_completion& operator=(const async_completion&) = delete;
407
408      __handler_type	completion_handler;
409      __result_type	result;
410    };
411
412
413  class execution_context
414  {
415  public:
416    class service
417    {
418    protected:
419      // construct / copy / destroy:
420
421      explicit
422      service(execution_context& __owner) : _M_context(__owner) { }
423
424      service(const service&) = delete;
425      service& operator=(const service&) = delete;
426
427      virtual ~service() { } // TODO should not be inline
428
429      // service observers:
430
431      execution_context& context() const noexcept { return _M_context; }
432
433    private:
434      // service operations:
435
436      virtual void shutdown() noexcept = 0;
437      virtual void notify_fork(fork_event) { }
438
439      friend class execution_context;
440      execution_context& _M_context;
441    };
442
443    // construct / copy / destroy:
444
445    execution_context() { }
446
447    execution_context(const execution_context&) = delete;
448    execution_context& operator=(const execution_context&) = delete;
449
450    virtual ~execution_context()
451    {
452      shutdown();
453      destroy();
454    }
455
456    // execution context operations:
457
458    void
459    notify_fork(fork_event __e)
460    {
461      auto __l = [=](auto& __svc) { __svc._M_ptr->notify_fork(__e); };
462      if (__e == fork_event::prepare)
463	std::for_each(_M_services.rbegin(), _M_services.rend(), __l);
464      else
465	std::for_each(_M_services.begin(), _M_services.end(), __l);
466    }
467
468  protected:
469    // execution context protected operations:
470
471    void
472    shutdown()
473    {
474      std::for_each(_M_services.rbegin(), _M_services.rend(),
475	  [=](auto& __svc) {
476	    if (__svc._M_active)
477	      {
478	        __svc._M_ptr->shutdown();
479		__svc._M_active = false;
480	      }
481	  });
482    }
483
484    void
485    destroy()
486    {
487      while (_M_services.size())
488	_M_services.pop_back();
489      _M_keys.clear();
490    }
491
492  protected:
493
494    template<typename _Service>
495      static void
496      _S_deleter(service* __svc) { delete static_cast<_Service*>(__svc); }
497
498    struct _ServicePtr
499    {
500      template<typename _Service>
501	explicit
502	_ServicePtr(_Service* __svc)
503	: _M_ptr(__svc, &_S_deleter<_Service>), _M_active(true) { }
504
505      std::unique_ptr<service, void(*)(service*)> _M_ptr;
506      bool _M_active;
507    };
508
509    mutable std::mutex _M_mutex;
510
511    // Sorted in order of beginning of service object lifetime.
512    std::list<_ServicePtr> _M_services;
513
514    template<typename _Service, typename... _Args>
515      service*
516      _M_add_svc(_Args&&... __args)
517      {
518	_M_services.push_back(
519	    _ServicePtr{new _Service{*this, std::forward<_Args>(__args)...}} );
520	return _M_services.back()._M_ptr.get();
521      }
522
523    using __key_type = void(*)();
524
525    template<typename _Key>
526      static __key_type
527      _S_key() { return reinterpret_cast<__key_type>(&_S_key<_Key>); }
528
529    std::unordered_map<__key_type, service*> _M_keys;
530
531    template<typename _Service>
532      friend typename _Service::key_type&
533      use_service(execution_context&);
534
535    template<typename _Service, typename... _Args>
536      friend _Service&
537      make_service(execution_context&, _Args&&...);
538
539    template<typename _Service>
540      friend bool
541      has_service(const execution_context&) noexcept;
542  };
543
544  // service access:
545
546  template<typename _Service>
547    typename _Service::key_type&
548    use_service(execution_context& __ctx)
549    {
550      using _Key = typename _Service::key_type;
551      static_assert(is_base_of<execution_context::service, _Key>::value,
552	  "a service type must derive from execution_context::service");
553      static_assert(is_base_of<_Key, _Service>::value,
554	  "a service type must match or derive from its key_type");
555      auto __key = execution_context::_S_key<_Key>();
556      std::lock_guard<std::mutex> __lock(__ctx._M_mutex);
557      auto& __svc = __ctx._M_keys[__key];
558      if (__svc == nullptr)
559	{
560	  __try {
561	    __svc = __ctx._M_add_svc<_Service>();
562	  } __catch(...) {
563	    __ctx._M_keys.erase(__key);
564	    __throw_exception_again;
565	  }
566	}
567      return static_cast<_Key&>(*__svc);
568    }
569
570  template<typename _Service, typename... _Args>
571    _Service&
572    make_service(execution_context& __ctx, _Args&&... __args)
573    {
574      using _Key = typename _Service::key_type;
575      static_assert(is_base_of<execution_context::service, _Key>::value,
576	  "a service type must derive from execution_context::service");
577      static_assert(is_base_of<_Key, _Service>::value,
578	  "a service type must match or derive from its key_type");
579      auto __key = execution_context::_S_key<_Key>();
580      std::lock_guard<std::mutex> __lock(__ctx._M_mutex);
581      auto& __svc = __ctx._M_keys[__key];
582      if (__svc != nullptr)
583	throw service_already_exists();
584      __try {
585	__svc = __ctx._M_add_svc<_Service>(std::forward<_Args>(__args)...);
586      } __catch(...) {
587	__ctx._M_keys.erase(__key);
588	__throw_exception_again;
589      }
590      return static_cast<_Service&>(*__svc);
591    }
592
593  template<typename _Service>
594    inline bool
595    has_service(const execution_context& __ctx) noexcept
596    {
597      using _Key = typename _Service::key_type;
598      static_assert(is_base_of<execution_context::service, _Key>::value,
599	  "a service type must derive from execution_context::service");
600      static_assert(is_base_of<_Key, _Service>::value,
601	  "a service type must match or derive from its key_type");
602      std::lock_guard<std::mutex> __lock(__ctx._M_mutex);
603      return __ctx._M_keys.count(execution_context::_S_key<_Key>());
604    }
605
606  template<typename _Tp, typename = __void_t<>>
607    struct __is_executor_impl : false_type
608    { };
609
610  // Check Executor requirements.
611  template<typename _Tp, typename _Up = remove_const_t<_Tp>>
612    auto
613    __executor_reqs(_Up* __x = 0, const _Up* __cx = 0, void(*__f)() = 0,
614		    const allocator<int>& __a = {})
615    -> enable_if_t<__is_value_constructible<_Tp>::value, __void_t<
616      decltype(*__cx == *__cx),
617      decltype(*__cx != *__cx),
618      decltype(__x->context()),
619      decltype(__x->on_work_started()),
620      decltype(__x->on_work_finished()),
621      decltype(__x->dispatch(std::move(__f), __a)),
622      decltype(__x->post(std::move(__f), __a)),
623      decltype(__x->defer(std::move(__f), __a))
624    >>;
625
626  template<typename _Tp>
627    struct __is_executor_impl<_Tp, decltype(__executor_reqs<_Tp>())>
628    : true_type
629    { };
630
631  template<typename _Tp>
632    struct is_executor : __is_executor_impl<_Tp>
633    { };
634
635  template<typename _Tp>
636    constexpr bool is_executor_v = is_executor<_Tp>::value;
637
638  template<typename _Tp, typename _Executor, typename = __void_t<>>
639    struct __uses_executor_impl : false_type
640    { };
641
642  template<typename _Tp, typename _Executor>
643    struct __uses_executor_impl<_Tp, _Executor,
644				__void_t<typename _Tp::executor_type>>
645    : is_convertible<_Executor, typename _Tp::executor_type>
646    { };
647
648  template<typename _Tp, typename _Executor>
649    struct uses_executor : __uses_executor_impl<_Tp, _Executor>::type
650    { };
651
652  template<typename _Tp, typename _Executor>
653    constexpr bool uses_executor_v = uses_executor<_Tp, _Executor>::value;
654
655  template<typename _Tp, typename _Executor>
656    class executor_binder
657    {
658      struct __use_exec { };
659
660    public:
661      // types:
662
663      typedef _Tp target_type;
664      typedef _Executor executor_type;
665
666      // construct / copy / destroy:
667
668      executor_binder(_Tp __t, const _Executor& __ex)
669      : executor_binder(__use_exec{}, std::move(__t), __ex)
670      { }
671
672      executor_binder(const executor_binder&) = default;
673      executor_binder(executor_binder&&) = default;
674
675      template<typename _Up, typename _OtherExecutor>
676	executor_binder(const executor_binder<_Up, _OtherExecutor>& __other)
677	: executor_binder(__use_exec{}, __other.get(), __other.get_executor())
678	{ }
679
680      template<typename _Up, typename _OtherExecutor>
681	executor_binder(executor_binder<_Up, _OtherExecutor>&& __other)
682	: executor_binder(__use_exec{}, std::move(__other.get()),
683			  __other.get_executor())
684	{ }
685
686      template<typename _Up, typename _OtherExecutor>
687	executor_binder(executor_arg_t, const _Executor& __ex,
688			const executor_binder<_Up, _OtherExecutor>& __other)
689	: executor_binder(__use_exec{}, __other.get(), __ex)
690	{ }
691
692      template<typename _Up, typename _OtherExecutor>
693	executor_binder(executor_arg_t, const _Executor& __ex,
694			executor_binder<_Up, _OtherExecutor>&& __other)
695	: executor_binder(__use_exec{}, std::move(__other.get()), __ex)
696	{ }
697
698      ~executor_binder();
699
700      // executor binder access:
701
702      _Tp& get() noexcept { return _M_target; }
703      const _Tp& get() const noexcept { return _M_target; }
704      executor_type get_executor() const noexcept { return _M_ex; }
705
706      // executor binder invocation:
707
708      template<class... _Args>
709	result_of_t<_Tp&(_Args&&...)>
710	operator()(_Args&&... __args)
711	{ return std::__invoke(get(), std::forward<_Args>(__args)...); }
712
713      template<class... _Args>
714	result_of_t<const _Tp&(_Args&&...)>
715	operator()(_Args&&... __args) const
716	{ return std::__invoke(get(), std::forward<_Args>(__args)...); }
717
718    private:
719      template<typename _Up>
720	using __use_exec_cond
721	  = __and_<uses_executor<_Tp, _Executor>,
722		   is_constructible<_Tp, executor_arg_t, _Executor, _Up>>;
723
724      template<typename _Up, typename _Exec, typename =
725	       enable_if_t<__use_exec_cond<_Up>::value>>
726	executor_binder(__use_exec, _Up&& __u, _Exec&& __ex)
727	: _M_ex(std::forward<_Exec>(__ex)),
728	  _M_target(executor_arg, _M_ex, std::forward<_Up>(__u))
729	{ }
730
731      template<typename _Up, typename _Exec, typename =
732	       enable_if_t<!__use_exec_cond<_Up>::value>>
733	executor_binder(__use_exec, _Up&& __u, const _Exec& __ex)
734	: _M_ex(std::forward<_Exec>(__ex)),
735	  _M_target(std::forward<_Up>(__u))
736	{ }
737
738      _Executor	_M_ex;
739      _Tp	_M_target;
740    };
741
742  template<typename _Tp, typename _Executor, typename _Signature>
743    class async_result<executor_binder<_Tp, _Executor>, _Signature>
744    {
745      using __inner = async_result<_Tp, _Signature>;
746
747    public:
748      using completion_handler_type =
749	executor_binder<typename __inner::completion_handler_type, _Executor>;
750
751      using return_type = typename __inner::return_type;
752
753      explicit
754      async_result(completion_handler_type& __h)
755      : _M_target(__h.get()) { }
756
757      async_result(const async_result&) = delete;
758      async_result& operator=(const async_result&) = delete;
759
760      return_type get() { return _M_target.get(); }
761
762    private:
763      __inner _M_target;
764    };
765
766  template<typename _Tp, typename _Executor, typename _ProtoAlloc>
767    struct associated_allocator<executor_binder<_Tp, _Executor>, _ProtoAlloc>
768    {
769      typedef associated_allocator_t<_Tp, _ProtoAlloc> type;
770
771      static type
772      get(const executor_binder<_Tp, _Executor>& __b,
773	  const _ProtoAlloc& __a = _ProtoAlloc()) noexcept
774      { return associated_allocator<_Tp, _ProtoAlloc>::get(__b.get(), __a); }
775    };
776
777  template<typename _Tp, typename _Executor, typename _Executor1>
778    struct associated_executor<executor_binder<_Tp, _Executor>, _Executor1>
779    {
780      typedef _Executor type;
781
782      static type
783      get(const executor_binder<_Tp, _Executor>& __b,
784	  const _Executor1& = _Executor1()) noexcept
785      { return __b.get_executor(); }
786    };
787
788  template<typename _Executor>
789    class executor_work_guard
790    {
791    public:
792      // types:
793
794      typedef _Executor executor_type;
795
796      // construct / copy / destroy:
797
798      explicit
799      executor_work_guard(const executor_type& __ex) noexcept
800      : _M_ex(__ex), _M_owns(true)
801      { _M_ex.on_work_started(); }
802
803      executor_work_guard(const executor_work_guard& __other) noexcept
804      : _M_ex(__other._M_ex), _M_owns(__other._M_owns)
805      {
806	if (_M_owns)
807	  _M_ex.on_work_started();
808      }
809
810      executor_work_guard(executor_work_guard&& __other) noexcept
811      : _M_ex(__other._M_ex), _M_owns(__other._M_owns)
812      { __other._M_owns = false; }
813
814      executor_work_guard& operator=(const executor_work_guard&) = delete;
815
816      ~executor_work_guard()
817      {
818	if (_M_owns)
819	  _M_ex.on_work_finished();
820      }
821
822      // executor work guard observers:
823
824      executor_type get_executor() const noexcept { return _M_ex; }
825
826      bool owns_work() const noexcept { return _M_owns; }
827
828      // executor work guard modifiers:
829
830      void reset() noexcept
831      {
832	if (_M_owns)
833	  _M_ex.on_work_finished();
834	_M_owns = false;
835      }
836
837    private:
838      _Executor	_M_ex;
839      bool	_M_owns;
840    };
841
842
843  class system_context : public execution_context
844  {
845  public:
846    // types:
847
848    typedef system_executor executor_type;
849
850    // construct / copy / destroy:
851
852    system_context() = delete;
853    system_context(const system_context&) = delete;
854    system_context& operator=(const system_context&) = delete;
855
856    ~system_context()
857    {
858      stop();
859      join();
860    }
861
862    // system_context operations:
863
864    executor_type get_executor() noexcept;
865
866    void stop()
867    {
868      lock_guard<mutex> __lock(_M_mtx);
869      _M_stopped = true;
870      _M_cv.notify_all();
871    }
872
873    bool stopped() const noexcept
874    {
875      lock_guard<mutex> __lock(_M_mtx);
876      return _M_stopped;
877    }
878
879    void join()
880    {
881      if (_M_thread.joinable())
882	_M_thread.join();
883    }
884
885  private:
886    friend system_executor;
887
888    struct __tag { };
889    system_context(__tag) { }
890
891    thread			_M_thread;
892    mutable mutex		_M_mtx;
893    condition_variable		_M_cv;
894    queue<function<void()>>	_M_tasks;
895    bool			_M_stopped = false;
896
897    void
898    _M_run()
899    {
900      while (true)
901	{
902	  function<void()> __f;
903	  {
904	    unique_lock<mutex> __lock(_M_mtx);
905	    _M_cv.wait(__lock,
906		       [this]{ return _M_stopped || !_M_tasks.empty(); });
907	    if (_M_stopped)
908	      return;
909	    __f = std::move(_M_tasks.front());
910	    _M_tasks.pop();
911	  }
912	  __f();
913	}
914    }
915
916    void
917    _M_post(std::function<void()> __f)
918    {
919      lock_guard<mutex> __lock(_M_mtx);
920      if (_M_stopped)
921	return;
922      if (!_M_thread.joinable())
923	_M_thread = std::thread(&system_context::_M_run, this);
924      _M_tasks.push(std::move(__f)); // XXX allocator not used
925      _M_cv.notify_one();
926    }
927
928    static system_context&
929    _S_get() noexcept
930    {
931      static system_context __sc(__tag{});
932      return __sc;
933    }
934  };
935
936  class system_executor
937  {
938  public:
939    // executor operations:
940
941    system_executor() { }
942
943    system_context&
944    context() const noexcept { return system_context::_S_get(); }
945
946    void on_work_started() const noexcept { }
947    void on_work_finished() const noexcept { }
948
949    template<typename _Func, typename _ProtoAlloc>
950      void
951      dispatch(_Func&& __f, const _ProtoAlloc& __a) const
952      { decay_t<_Func>{std::forward<_Func>(__f)}(); }
953
954    template<typename _Func, typename _ProtoAlloc>
955      void
956      post(_Func&& __f, const _ProtoAlloc&) const // XXX allocator not used
957      {
958	system_context::_S_get()._M_post(std::forward<_Func>(__f));
959      }
960
961    template<typename _Func, typename _ProtoAlloc>
962      void
963      defer(_Func&& __f, const _ProtoAlloc& __a) const
964      { post(std::forward<_Func>(__f), __a); }
965  };
966
967  inline system_executor
968  system_context::get_executor() noexcept
969  { return {}; }
970
971  class bad_executor : public std::exception
972  {
973    virtual const char* what() const noexcept { return "bad executor"; }
974  };
975
976  inline void __throw_bad_executor() // TODO make non-inline
977  {
978#if __cpp_exceptions
979    throw bad_executor();
980#else
981    __builtin_abort();
982#endif
983  }
984
985  class executor
986  {
987  public:
988    // construct / copy / destroy:
989
990    executor() noexcept = default;
991
992    executor(nullptr_t) noexcept { }
993    executor(const executor&) noexcept = default;
994    executor(executor&&) noexcept = default;
995
996    template<typename _Executor>
997      executor(_Executor __e)
998      : _M_target(make_shared<_Tgt1<_Executor>>(std::move(__e)))
999      { }
1000
1001    template<typename _Executor, typename _ProtoAlloc>
1002      executor(allocator_arg_t, const _ProtoAlloc& __a, _Executor __e)
1003      : _M_target(allocate_shared<_Tgt2<_Executor, _ProtoAlloc>>(__a,
1004	    std::move(__e), __a))
1005      { }
1006
1007    executor& operator=(const executor&) noexcept = default;
1008    executor& operator=(executor&&) noexcept = default;
1009
1010    executor&
1011    operator=(nullptr_t) noexcept
1012    {
1013      _M_target = nullptr;
1014      return *this;
1015    }
1016
1017    template<typename _Executor>
1018      executor&
1019      operator=(_Executor __e)
1020      {
1021	executor(std::move(__e)).swap(*this);
1022	return *this;
1023      }
1024
1025    ~executor() = default;
1026
1027    // executor modifiers:
1028
1029    void
1030    swap(executor& __other) noexcept
1031    { _M_target.swap(__other._M_target); }
1032
1033    template<typename _Executor, typename _Alloc>
1034      void
1035      assign(_Executor __e, const _Alloc& __a)
1036      { executor(allocator_arg, __a, std::move(__e)).swap(*this); }
1037
1038    // executor operations:
1039
1040    execution_context&
1041    context() const noexcept
1042    {
1043      __glibcxx_assert( _M_target );
1044      return _M_target->context();
1045    }
1046
1047    void
1048    on_work_started() const noexcept
1049    {
1050      __glibcxx_assert( _M_target );
1051      return _M_target->on_work_started();
1052    }
1053
1054    void
1055    on_work_finished() const noexcept
1056    {
1057      __glibcxx_assert( _M_target );
1058      return _M_target->on_work_finished();
1059    }
1060
1061    template<typename _Func, typename _Alloc>
1062      void
1063      dispatch(_Func&& __f, const _Alloc& __a) const
1064      {
1065	if (!_M_target)
1066	  __throw_bad_executor();
1067	// _M_target->dispatch({allocator_arg, __a, std::forward<_Func>(__f)});
1068	_M_target->dispatch(std::forward<_Func>(__f));
1069      }
1070
1071    template<typename _Func, typename _Alloc>
1072      void
1073      post(_Func&& __f, const _Alloc& __a) const
1074      {
1075	if (!_M_target)
1076	  __throw_bad_executor();
1077	// _M_target->post({allocator_arg, __a, std::forward<_Func>(__f)});
1078	_M_target->post(std::forward<_Func>(__f));
1079      }
1080
1081    template<typename _Func, typename _Alloc>
1082      void
1083      defer(_Func&& __f, const _Alloc& __a) const
1084      {
1085	if (!_M_target)
1086	  __throw_bad_executor();
1087	// _M_target->defer({allocator_arg, __a, std::forward<_Func>(__f)});
1088	_M_target->defer(std::forward<_Func>(__f));
1089      }
1090
1091    // executor capacity:
1092
1093    explicit operator bool() const noexcept
1094    { return static_cast<bool>(_M_target); }
1095
1096    // executor target access:
1097
1098#if __cpp_rtti
1099    const type_info&
1100    target_type() const noexcept
1101    {
1102      if (_M_target)
1103	return *static_cast<const type_info*>(_M_target->target_type());
1104      return typeid(void);
1105    }
1106#endif
1107
1108    template<typename _Executor>
1109      _Executor*
1110      target() noexcept
1111      {
1112	void* __p = nullptr;
1113	if (_M_target)
1114	  {
1115	    if (_M_target->_M_func == &_Tgt1<remove_cv_t<_Executor>>::_S_func)
1116	      __p = _M_target->_M_func(_M_target.get(), nullptr);
1117#if __cpp_rtti
1118	    else
1119	      __p = _M_target->target(&typeid(_Executor));
1120#endif
1121	  }
1122	return static_cast<_Executor*>(__p);
1123      }
1124
1125    template<typename _Executor>
1126      const _Executor*
1127      target() const noexcept
1128      {
1129	const void* __p = nullptr;
1130	if (_M_target)
1131	  {
1132	    if (_M_target->_M_func == &_Tgt1<remove_cv_t<_Executor>>::_S_func)
1133	      return (_Executor*)_M_target->_M_func(_M_target.get(), nullptr);
1134#if __cpp_rtti
1135	    else
1136	      __p = _M_target->target(&typeid(_Executor));
1137#endif
1138	  }
1139	return static_cast<const _Executor*>(__p);
1140      }
1141
1142  private:
1143    struct _Tgt
1144    {
1145      virtual void on_work_started() const noexcept = 0;
1146      virtual void on_work_finished() const noexcept = 0;
1147      virtual execution_context& context() const noexcept = 0;
1148      virtual void dispatch(std::function<void()>) const = 0;
1149      virtual void post(std::function<void()>) const = 0;
1150      virtual void defer(std::function<void()>) const = 0;
1151      virtual const void* target_type() const noexcept = 0;
1152      virtual void* target(const void*) noexcept = 0;
1153      virtual bool _M_equals(_Tgt*) const noexcept = 0;
1154
1155      using _Func = void* (_Tgt*, const _Tgt*);
1156      _Func* _M_func; // Provides access to target without RTTI
1157    };
1158
1159    template<typename _Ex>
1160      struct _Tgt1 : _Tgt
1161      {
1162	explicit
1163	_Tgt1(_Ex&& __ex)
1164	: _M_ex(std::move(__ex))
1165	{ this->_M_func = &_S_func; }
1166
1167	void
1168	on_work_started() const noexcept override
1169	{ _M_ex.on_work_started(); }
1170
1171	void
1172	on_work_finished() const noexcept override
1173	{ _M_ex.on_work_finished(); }
1174
1175	execution_context&
1176	context() const noexcept override
1177	{ return _M_ex.context(); }
1178
1179	void
1180	dispatch(std::function<void()> __f) const override
1181	{ _M_ex.dispatch(std::move(__f), allocator<void>()); }
1182
1183	void
1184	post(std::function<void()> __f) const override
1185	{ _M_ex.post(std::move(__f), allocator<void>()); }
1186
1187	void
1188	defer(std::function<void()> __f) const override
1189	{ _M_ex.defer(std::move(__f), allocator<void>()); }
1190
1191	const void*
1192	target_type() const noexcept override
1193	{
1194#if __cpp_rtti
1195	  return &typeid(_Ex);
1196#else
1197	  return nullptr;
1198#endif
1199	}
1200
1201	void*
1202	target(const void* __ti) noexcept override
1203	{
1204#if __cpp_rtti
1205	  if (*static_cast<const type_info*>(__ti) == typeid(_Ex))
1206	    return std::__addressof(_M_ex);
1207#endif
1208	  return nullptr;
1209	}
1210
1211	bool
1212	_M_equals(_Tgt* __tgt) const noexcept override
1213	{
1214#if __cpp_rtti
1215	  if (const void* __p = __tgt->target(&typeid(_Ex)))
1216	    return *static_cast<const _Ex*>(__p) == _M_ex;
1217#endif
1218	  return false;
1219	}
1220
1221	_Ex _M_ex [[__no_unique_address__]];
1222
1223	static void*
1224	_S_func(_Tgt* __p, const _Tgt* __q) noexcept
1225	{
1226	  auto& __ex = static_cast<_Tgt1*>(__p)->_M_ex;
1227	  if (__q)
1228	    {
1229	      if (__ex == static_cast<const _Tgt1*>(__q)->_M_ex)
1230		return __p;
1231	      else
1232		return nullptr;
1233	    }
1234	  else
1235	    return std::__addressof(__ex);
1236	}
1237      };
1238
1239    template<typename _Ex, typename _Alloc>
1240      struct _Tgt2 : _Tgt1<_Ex>
1241      {
1242	explicit
1243	_Tgt2(_Ex&& __ex, const _Alloc& __a)
1244	: _Tgt1<_Ex>(std::move(__ex)), _M_alloc(__a) { }
1245
1246	void
1247	dispatch(std::function<void()> __f) const override
1248	{ this->_M_ex.dispatch(std::move(__f), _M_alloc); }
1249
1250	void
1251	post(std::function<void()> __f) const override
1252	{ this->_M_ex.post(std::move(__f), _M_alloc); }
1253
1254	void
1255	defer(std::function<void()> __f) const override
1256	{ this->_M_ex.defer(std::move(__f), _M_alloc); }
1257
1258	_Alloc _M_alloc [[__no_unique_address__]];
1259      };
1260
1261    // Partial specialization for std::allocator<T>.
1262    // Don't store the allocator.
1263    template<typename _Ex, typename _Tp>
1264      struct _Tgt2<_Ex, std::allocator<_Tp>> : _Tgt1<_Ex>
1265      { };
1266
1267    friend bool
1268    operator==(const executor& __a, const executor& __b) noexcept
1269    {
1270      _Tgt* __ta = __a._M_target.get();
1271      _Tgt* __tb = __b._M_target.get();
1272      if (__ta == __tb)
1273	return true;
1274      if (!__ta || !__tb)
1275	return false;
1276      if (__ta->_M_func == __tb->_M_func)
1277	return __ta->_M_func(__ta, __tb);
1278      return __ta->_M_equals(__tb);
1279    }
1280
1281    shared_ptr<_Tgt> _M_target;
1282  };
1283
1284  template<> struct is_executor<executor> : true_type { };
1285
1286  /// executor comparisons
1287  inline bool
1288  operator==(const executor& __e, nullptr_t) noexcept
1289  { return !__e; }
1290
1291  inline bool
1292  operator==(nullptr_t, const executor& __e) noexcept
1293  { return !__e; }
1294
1295  inline bool
1296  operator!=(const executor& __a, const executor& __b) noexcept
1297  { return !(__a == __b); }
1298
1299  inline bool
1300  operator!=(const executor& __e, nullptr_t) noexcept
1301  { return (bool)__e; }
1302
1303  inline bool
1304  operator!=(nullptr_t, const executor& __e) noexcept
1305  { return (bool)__e; }
1306
1307  /// Swap two executor objects.
1308  inline void swap(executor& __a, executor& __b) noexcept { __a.swap(__b); }
1309
1310
1311  template<typename _CompletionHandler>
1312    struct __dispatcher
1313    {
1314      explicit
1315      __dispatcher(_CompletionHandler& __h)
1316      : _M_h(std::move(__h)), _M_w(net::make_work_guard(_M_h))
1317      { }
1318
1319      void operator()()
1320      {
1321	auto __alloc = net::get_associated_allocator(_M_h);
1322	_M_w.get_executor().dispatch(std::move(_M_h), __alloc);
1323	_M_w.reset();
1324      }
1325
1326      _CompletionHandler _M_h;
1327      decltype(net::make_work_guard(_M_h)) _M_w;
1328    };
1329
1330  template<typename _CompletionHandler>
1331    inline __dispatcher<_CompletionHandler>
1332    __make_dispatcher(_CompletionHandler& __h)
1333    { return __dispatcher<_CompletionHandler>{__h}; }
1334
1335
1336
1337  // dispatch:
1338
1339  template<typename _CompletionToken>
1340    inline __deduced_t<_CompletionToken, void()>
1341    dispatch(_CompletionToken&& __token)
1342    {
1343      async_completion<_CompletionToken, void()> __cmpl{__token};
1344      auto __ex = net::get_associated_executor(__cmpl.completion_handler);
1345      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
1346      __ex.dispatch(std::move(__cmpl.completion_handler), __alloc);
1347      return __cmpl.result.get();
1348    }
1349
1350  template<typename _Executor, typename _CompletionToken>
1351    inline
1352    enable_if_t<is_executor<_Executor>::value,
1353		__deduced_t<_CompletionToken, void()>>
1354    dispatch(const _Executor& __ex, _CompletionToken&& __token)
1355    {
1356      async_completion<_CompletionToken, void()> __cmpl{__token};
1357      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
1358      __ex.dispatch(net::__make_dispatcher(__cmpl.completion_handler),
1359		    __alloc);
1360      return __cmpl.result.get();
1361    }
1362
1363  template<typename _ExecutionContext, typename _CompletionToken>
1364    inline
1365    enable_if_t<__is_exec_context<_ExecutionContext>::value,
1366		__deduced_t<_CompletionToken, void()>>
1367    dispatch(_ExecutionContext& __ctx, _CompletionToken&& __token)
1368    {
1369      return net::dispatch(__ctx.get_executor(),
1370			   forward<_CompletionToken>(__token));
1371    }
1372
1373  // post:
1374
1375  template<typename _CompletionToken>
1376    inline __deduced_t<_CompletionToken, void()>
1377    post(_CompletionToken&& __token)
1378    {
1379      async_completion<_CompletionToken, void()> __cmpl{__token};
1380      auto __ex = net::get_associated_executor(__cmpl.completion_handler);
1381      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
1382      __ex.post(std::move(__cmpl.completion_handler), __alloc);
1383      return __cmpl.result.get();
1384    }
1385
1386  template<typename _Executor, typename _CompletionToken>
1387    inline
1388    enable_if_t<is_executor<_Executor>::value,
1389		__deduced_t<_CompletionToken, void()>>
1390    post(const _Executor& __ex, _CompletionToken&& __token)
1391    {
1392      async_completion<_CompletionToken, void()> __cmpl{__token};
1393      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
1394      __ex.post(net::__make_dispatcher(__cmpl.completion_handler), __alloc);
1395      return __cmpl.result.get();
1396    }
1397
1398  template<typename _ExecutionContext, typename _CompletionToken>
1399    inline
1400    enable_if_t<__is_exec_context<_ExecutionContext>::value,
1401		__deduced_t<_CompletionToken, void()>>
1402    post(_ExecutionContext& __ctx, _CompletionToken&& __token)
1403    {
1404      return net::post(__ctx.get_executor(),
1405		       forward<_CompletionToken>(__token));
1406    }
1407
1408  // defer:
1409
1410  template<typename _CompletionToken>
1411    inline __deduced_t<_CompletionToken, void()>
1412    defer(_CompletionToken&& __token)
1413    {
1414      async_completion<_CompletionToken, void()> __cmpl{__token};
1415      auto __ex = net::get_associated_executor(__cmpl.completion_handler);
1416      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
1417      __ex.defer(std::move(__cmpl.completion_handler), __alloc);
1418      return __cmpl.result.get();
1419    }
1420
1421  template<typename _Executor, typename _CompletionToken>
1422    inline
1423    enable_if_t<is_executor<_Executor>::value,
1424		__deduced_t<_CompletionToken, void()>>
1425    defer(const _Executor& __ex, _CompletionToken&& __token)
1426    {
1427      async_completion<_CompletionToken, void()> __cmpl{__token};
1428      auto __alloc = net::get_associated_allocator(__cmpl.completion_handler);
1429      __ex.defer(net::__make_dispatcher(__cmpl.completion_handler), __alloc);
1430      return __cmpl.result.get();
1431    }
1432
1433  template<typename _ExecutionContext, typename _CompletionToken>
1434    inline
1435    enable_if_t<__is_exec_context<_ExecutionContext>::value,
1436		__deduced_t<_CompletionToken, void()>>
1437    defer(_ExecutionContext& __ctx, _CompletionToken&& __token)
1438    {
1439      return net::defer(__ctx.get_executor(),
1440			forward<_CompletionToken>(__token));
1441    }
1442
1443
1444  template<typename _Executor>
1445    class strand
1446    {
1447    public:
1448      // types:
1449
1450      typedef _Executor inner_executor_type;
1451
1452      // construct / copy / destroy:
1453
1454      strand(); // TODO make state
1455
1456      explicit strand(_Executor __ex) : _M_inner_ex(__ex) { } // TODO make state
1457
1458      template<typename _Alloc>
1459	strand(allocator_arg_t, const _Alloc& __a, _Executor __ex)
1460	: _M_inner_ex(__ex) { } // TODO make state
1461
1462      strand(const strand& __other) noexcept
1463      : _M_state(__other._M_state), _M_inner_ex(__other._M_inner_ex) { }
1464
1465      strand(strand&& __other) noexcept
1466      : _M_state(std::move(__other._M_state)),
1467	_M_inner_ex(std::move(__other._M_inner_ex)) { }
1468
1469      template<typename _OtherExecutor>
1470	strand(const strand<_OtherExecutor>& __other) noexcept
1471	: _M_state(__other._M_state), _M_inner_ex(__other._M_inner_ex) { }
1472
1473      template<typename _OtherExecutor>
1474	strand(strand<_OtherExecutor>&& __other) noexcept
1475	: _M_state(std::move(__other._M_state)),
1476	  _M_inner_ex(std::move(__other._M_inner_ex)) { }
1477
1478      strand&
1479      operator=(const strand& __other) noexcept
1480      {
1481	static_assert(is_copy_assignable<_Executor>::value,
1482		      "inner executor type must be CopyAssignable");
1483
1484	// TODO lock __other
1485	// TODO copy state
1486	_M_inner_ex = __other._M_inner_ex;
1487	return *this;
1488      }
1489
1490      strand&
1491      operator=(strand&& __other) noexcept
1492      {
1493	static_assert(is_move_assignable<_Executor>::value,
1494		      "inner executor type must be MoveAssignable");
1495
1496	// TODO move state
1497	_M_inner_ex = std::move(__other._M_inner_ex);
1498	return *this;
1499      }
1500
1501      template<typename _OtherExecutor>
1502	strand&
1503	operator=(const strand<_OtherExecutor>& __other) noexcept
1504	{
1505	  static_assert(is_convertible<_OtherExecutor, _Executor>::value,
1506			"inner executor type must be compatible");
1507
1508	  // TODO lock __other
1509	  // TODO copy state
1510	  _M_inner_ex = __other._M_inner_ex;
1511	  return *this;
1512	}
1513
1514      template<typename _OtherExecutor>
1515	strand&
1516	operator=(strand<_OtherExecutor>&& __other) noexcept
1517	{
1518	  static_assert(is_convertible<_OtherExecutor, _Executor>::value,
1519			"inner executor type must be compatible");
1520
1521	  // TODO move state
1522	  _M_inner_ex = std::move(__other._M_inner_ex);
1523	  return *this;
1524	}
1525
1526      ~strand()
1527      {
1528	// the task queue outlives this object if non-empty
1529	// TODO create circular ref in queue?
1530      }
1531
1532      // strand operations:
1533
1534      inner_executor_type
1535      get_inner_executor() const noexcept
1536      { return _M_inner_ex; }
1537
1538      bool
1539      running_in_this_thread() const noexcept
1540      { return std::this_thread::get_id() == _M_state->_M_running_on; }
1541
1542      execution_context&
1543      context() const noexcept
1544      { return _M_inner_ex.context(); }
1545
1546      void on_work_started() const noexcept { _M_inner_ex.on_work_started(); }
1547      void on_work_finished() const noexcept { _M_inner_ex.on_work_finished(); }
1548
1549      template<typename _Func, typename _Alloc>
1550	void
1551	dispatch(_Func&& __f, const _Alloc& __a) const
1552	{
1553	  if (running_in_this_thread())
1554	    decay_t<_Func>{std::forward<_Func>(__f)}();
1555	  else
1556	    post(std::forward<_Func>(__f), __a);
1557	}
1558
1559      template<typename _Func, typename _Alloc>
1560	void
1561	post(_Func&& __f, const _Alloc& __a) const; // TODO
1562
1563      template<typename _Func, typename _Alloc>
1564	void
1565	defer(_Func&& __f, const _Alloc& __a) const
1566	{ post(std::forward<_Func>(__f), __a); }
1567
1568    private:
1569      friend bool
1570      operator==(const strand& __a, const strand& __b)
1571      { return __a._M_state == __b._M_state; }
1572
1573      // TODO add synchronised queue
1574      struct _State
1575      {
1576	std::thread::id _M_running_on;
1577      };
1578      shared_ptr<_State> _M_state;
1579      _Executor _M_inner_ex;
1580    };
1581
1582#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
1583
1584  // Completion token for asynchronous operations initiated with use_future.
1585  template<typename _Func, typename _Alloc>
1586    struct __use_future_ct
1587    {
1588      std::tuple<_Func, _Alloc> _M_t;
1589    };
1590
1591  template<typename _ProtoAllocator = allocator<void>>
1592    class use_future_t
1593    {
1594    public:
1595      // use_future_t types:
1596      typedef _ProtoAllocator allocator_type;
1597
1598      // use_future_t members:
1599      constexpr use_future_t() noexcept : _M_alloc() { }
1600
1601      explicit
1602      use_future_t(const _ProtoAllocator& __a) noexcept : _M_alloc(__a) { }
1603
1604      template<class _OtherAllocator>
1605	use_future_t<_OtherAllocator>
1606	rebind(const _OtherAllocator& __a) const noexcept
1607	{ return use_future_t<_OtherAllocator>(__a); }
1608
1609      allocator_type get_allocator() const noexcept { return _M_alloc; }
1610
1611      template<typename _Func>
1612	auto
1613	operator()(_Func&& __f) const
1614	{
1615	  using _Token = __use_future_ct<decay_t<_Func>, _ProtoAllocator>;
1616	  return _Token{ {std::forward<_Func>(__f), _M_alloc} };
1617	}
1618
1619    private:
1620      _ProtoAllocator _M_alloc;
1621    };
1622
1623  constexpr use_future_t<> use_future = use_future_t<>();
1624
1625  template<typename _Func, typename _Alloc, typename _Res, typename... _Args>
1626    class async_result<__use_future_ct<_Func, _Alloc>, _Res(_Args...)>;
1627
1628  template<typename _Result, typename _Executor>
1629    struct __use_future_ex;
1630
1631  // Completion handler for asynchronous operations initiated with use_future.
1632  template<typename _Func, typename... _Args>
1633    struct __use_future_ch
1634    {
1635      template<typename _Alloc>
1636	explicit
1637	__use_future_ch(__use_future_ct<_Func, _Alloc>&& __token)
1638	: _M_f{ std::move(std::get<0>(__token._M_t)) },
1639	  _M_promise{ std::get<1>(__token._M_t) }
1640	{ }
1641
1642      void
1643      operator()(_Args&&... __args)
1644      {
1645	__try
1646	  {
1647	    _M_promise.set_value(_M_f(std::forward<_Args>(__args)...));
1648	  }
1649	__catch(__cxxabiv1::__forced_unwind&)
1650	  {
1651	    __throw_exception_again;
1652	  }
1653	__catch(...)
1654	  {
1655	    _M_promise.set_exception(std::current_exception());
1656	  }
1657      }
1658
1659      using __result = result_of_t<_Func(decay_t<_Args>...)>;
1660
1661      future<__result> get_future() { return _M_promise.get_future(); }
1662
1663    private:
1664      template<typename _Result, typename _Executor>
1665	friend struct __use_future_ex;
1666
1667      _Func _M_f;
1668      mutable promise<__result> _M_promise;
1669    };
1670
1671  // Specialization of async_result for operations initiated with use_future.
1672  template<typename _Func, typename _Alloc, typename _Res, typename... _Args>
1673    class async_result<__use_future_ct<_Func, _Alloc>, _Res(_Args...)>
1674    {
1675    public:
1676      using completion_handler_type = __use_future_ch<_Func, _Args...>;
1677      using return_type = future<typename completion_handler_type::__result>;
1678
1679      explicit
1680      async_result(completion_handler_type& __h)
1681      : _M_future(__h.get_future())
1682      { }
1683
1684      async_result(const async_result&) = delete;
1685      async_result& operator=(const async_result&) = delete;
1686
1687      return_type get() { return std::move(_M_future); }
1688
1689    private:
1690      return_type _M_future;
1691    };
1692
1693  template<typename _Result, typename _Executor>
1694    struct __use_future_ex
1695    {
1696      template<typename _Handler>
1697      __use_future_ex(const _Handler& __h, _Executor __ex)
1698      : _M_t(__h._M_promise, __ex)
1699      { }
1700
1701      template<typename _Fn, typename _Alloc>
1702	void
1703	dispatch(_Fn&& __fn)
1704	{
1705	  __try
1706	    {
1707	      std::get<1>(_M_t).dispatch(std::forward<_Fn>(__fn));
1708	    }
1709	  __catch(__cxxabiv1::__forced_unwind&)
1710	    {
1711	      __throw_exception_again;
1712	    }
1713	  __catch(...)
1714	    {
1715	      std::get<0>(_M_t).set_exception(std::current_exception());
1716	    }
1717	}
1718
1719      template<typename _Fn, typename _Alloc>
1720	void
1721	post(_Fn&& __fn)
1722	{
1723	  __try
1724	    {
1725	      std::get<1>(_M_t).post(std::forward<_Fn>(__fn));
1726	    }
1727	  __catch(__cxxabiv1::__forced_unwind&)
1728	    {
1729	      __throw_exception_again;
1730	    }
1731	  __catch(...)
1732	    {
1733	      std::get<0>(_M_t).set_exception(std::current_exception());
1734	    }
1735	}
1736
1737      template<typename _Fn, typename _Alloc>
1738	void
1739	defer(_Fn&& __fn)
1740	{
1741	  __try
1742	    {
1743	      std::get<1>(_M_t).defer(std::forward<_Fn>(__fn));
1744	    }
1745	  __catch(__cxxabiv1::__forced_unwind&)
1746	    {
1747	      __throw_exception_again;
1748	    }
1749	  __catch(...)
1750	    {
1751	      std::get<0>(_M_t).set_exception(std::current_exception());
1752	    }
1753	}
1754
1755    private:
1756      tuple<promise<_Result>&, _Executor> _M_t;
1757    };
1758
1759  template<typename _Func, typename... _Args, typename _Executor>
1760    struct associated_executor<__use_future_ch<_Func, _Args...>, _Executor>
1761    {
1762    private:
1763      using __handler = __use_future_ch<_Func, _Args...>;
1764
1765      using type = __use_future_ex<typename __handler::__result, _Executor>;
1766
1767      static type
1768      get(const __handler& __h, const _Executor& __ex)
1769      { return { __h, __ex }; }
1770    };
1771
1772#if 0
1773
1774  // [async.use.future.traits]
1775  template<typename _Allocator, typename _Ret, typename... _Args>
1776    class handler_type<use_future_t<_Allocator>, _Ret(_Args...)> // TODO uglify name
1777    {
1778      template<typename... _Args>
1779	struct __is_error_result : false_type { };
1780
1781      template<typename... _Args>
1782	struct __is_error_result<error_code, _Args...> : true_type { };
1783
1784      template<typename... _Args>
1785	struct __is_error_result<exception_ptr, _Args...> : true_type { };
1786
1787      static exception_ptr
1788      _S_exptr(exception_ptr& __ex)
1789      { return std::move(__ex); }
1790
1791      static exception_ptr
1792      _S_exptr(const error_code& __ec)
1793      { return make_exception_ptr(system_error(__ec)); }
1794
1795      template<bool _IsError, typename... _UArgs>
1796	struct _Type;
1797
1798      // N == 0
1799      template<bool _IsError>
1800	struct _Type<_IsError>
1801	{
1802	  std::promise<void> _M_promise;
1803
1804	  void
1805	  operator()()
1806	  {
1807	    _M_promise.set_value();
1808	  }
1809	};
1810
1811      // N == 1, U0 is error_code or exception_ptr
1812      template<typename _UArg0>
1813	struct _Type<true, _UArg0>
1814	{
1815	  std::promise<void> _M_promise;
1816
1817	  template<typename _Arg0>
1818	    void
1819	    operator()(_Arg0&& __a0)
1820	    {
1821	      if (__a0)
1822		_M_promise.set_exception(_S_exptr(__a0));
1823	      else
1824		_M_promise.set_value();
1825	    }
1826	};
1827
1828      // N == 1, U0 is not error_code or exception_ptr
1829      template<typename _UArg0>
1830	struct _Type<false, _UArg0>
1831	{
1832	  std::promise<_UArg0> _M_promise;
1833
1834	  template<typename _Arg0>
1835	    void
1836	    operator()(_Arg0&& __a0)
1837	    {
1838	      _M_promise.set_value(std::forward<_Arg0>(__a0));
1839	    }
1840	};
1841
1842      // N == 2, U0 is error_code or exception_ptr
1843      template<typename _UArg0, typename _UArg1>
1844	struct _Type<true, _UArg0, _UArg1>
1845	{
1846	  std::promise<_UArg1> _M_promise;
1847
1848	  template<typename _Arg0, typename _Arg1>
1849	    void
1850	    operator()(_Arg0&& __a0, _Arg1&& __a1)
1851	    {
1852	      if (__a0)
1853		_M_promise.set_exception(_S_exptr(__a0));
1854	      else
1855		_M_promise.set_value(std::forward<_Arg1>(__a1));
1856	    }
1857	};
1858
1859      // N >= 2, U0 is not error_code or exception_ptr
1860      template<typename... _UArgs>
1861	struct _Type<false, _UArgs...>
1862	{
1863	  static_assert(sizeof...(_UArgs) > 1, "wrong partial specialization");
1864
1865	  std::promise<tuple<_UArgs...>> _M_promise;
1866
1867	  template<typename... _Args>
1868	    void
1869	    operator()(_Args&&... __args)
1870	    {
1871	      _M_promise.set_value(
1872		  std::forward_as_tuple(std::forward<_Args>(__args)...));
1873	    }
1874	};
1875
1876      // N > 2, U0 is error_code or exception_ptr
1877      template<typename _UArg0, typename... _UArgs>
1878	struct _Type<true, _UArg0, _UArgs...>
1879	{
1880	  static_assert(sizeof...(_UArgs) > 1, "wrong partial specialization");
1881
1882	  std::promise<tuple<_UArgs...>> _M_promise;
1883
1884	  template<typename _Arg0, typename... _Args>
1885	    void
1886	    operator()(_Arg0&& __a0, _Args&&... __args)
1887	    {
1888	      if (__a0)
1889		_M_promise.set_exception(_S_exptr(__a0));
1890	      else
1891		_M_promise.set_value(
1892		    std::forward_as_tuple(std::forward<_Args>(__args)...));
1893	    }
1894	};
1895
1896    public:
1897      using type =
1898	_Type<__is_error_result<_Args...>::value, decay_t<_Args>...>;
1899    };
1900
1901
1902  template<typename _Alloc, typename _Ret, typename... _Args>
1903    struct async_result<use_future_t<_Alloc>, _Ret(_Args...)>
1904    {
1905      using completion_handler_type
1906	= typename handler_type<use_future_t<_Alloc>, _Ret(_Args...)>::type;
1907
1908      using return_type = void; // XXX TODO ???;
1909
1910      explicit
1911      async_result(completion_handler_type& __h) : _M_handler(__h) { }
1912
1913      auto get() { return _M_handler._M_provider.get_future(); }
1914
1915      async_result(const async_result&) = delete;
1916      async_result& operator=(const async_result&) = delete;
1917
1918      return_type get() { return _M_handler._M_promise.get_future(); }
1919
1920    private:
1921      completion_handler_type& _M_handler;
1922    };
1923
1924  // TODO specialize associated_executor for
1925  // async_result<use_future_t<A>, Sig>::completion_handler_type
1926  // to use a __use_future_ex
1927  // (probably need to move _Type outside of handler_type so we don't have
1928  // a non-deduced context)
1929
1930
1931#endif
1932
1933  // [async.packaged.task.specializations]
1934  template<typename _Ret, typename... _Args, typename _Signature>
1935    class async_result<packaged_task<_Ret(_Args...)>, _Signature>
1936    {
1937    public:
1938      using completion_handler_type = packaged_task<_Ret(_Args...)>;
1939      using return_type = future<_Ret>;
1940
1941      explicit
1942      async_result(completion_handler_type& __h)
1943      : _M_future(__h.get_future()) { }
1944
1945      async_result(const async_result&) = delete;
1946      async_result& operator=(const async_result&) = delete;
1947
1948      return_type get() { return std::move(_M_future); }
1949
1950    private:
1951      return_type _M_future;
1952    };
1953
1954#endif
1955
1956  /// @}
1957
1958} // namespace v1
1959} // namespace net
1960} // namespace experimental
1961
1962  template<typename _Alloc>
1963    struct uses_allocator<experimental::net::executor, _Alloc>
1964    : true_type {};
1965
1966_GLIBCXX_END_NAMESPACE_VERSION
1967} // namespace std
1968
1969#endif // C++14
1970
1971#endif // _GLIBCXX_EXPERIMENTAL_EXECUTOR
1972