26#ifndef MYSQL_HARNESS_NET_TS_EXECUTOR_H_ 
   27#define MYSQL_HARNESS_NET_TS_EXECUTOR_H_ 
   30#include <condition_variable> 
   40#include <unordered_map> 
   51template <
class CompletionToken, 
class Signature>
 
   54template <
class CompletionToken, 
class Signature>
 
   68template <
class CompletionToken, 
class Signature>
 
   69class async_completion;
 
   71template <
class CompletionToken, 
class Signature>
 
   80      std::is_same<CompletionToken, completion_handler_type>::value,
 
   99template <class T, class ProtoAllocator = 
std::allocator<
void>>
 
  102template <class T, class ProtoAllocator = 
std::allocator<
void>>
 
  108template <class T, class ProtoAllocator, typename = 
std::void_t<>>
 
  112  static type __get(
const T & , 
const ProtoAllocator &a) 
noexcept {
 
  117template <
class T, 
class ProtoAllocator>
 
  119                                 std::void_t<typename T::allocator_type>> {
 
  120  using type = 
typename T::allocator_type;
 
  122  static type __get(
const T &t, 
const ProtoAllocator & ) 
noexcept {
 
  123    return t.get_allocator();
 
  127template <
class T, 
class ProtoAllocator>
 
  129  static auto get(
const T &t,
 
  130                  const ProtoAllocator &a = ProtoAllocator()) noexcept {
 
  132    return Impl::__get(t, a);
 
  142template <
class T, 
class ProtoAllocator>
 
  144    const T &t, 
const ProtoAllocator &a) 
noexcept {
 
  151  using std::logic_error::logic_error;
 
  185  template <
class Service>
 
  187    delete static_cast<Service *
>(svc);
 
  191    template <
class Service>
 
  207    return std::type_index(
typeid(
Key));
 
  215  std::unordered_map<service_key_type, service *> 
keys_;
 
  217  template <
typename Service, 
class... Args>
 
  220        ServicePtr{
new Service{*
this, std::forward<Args>(args)...}});
 
  225  template <
class Service>
 
  228  template <
class Service>
 
  231  template <
class Service, 
class... Args>
 
  236template <
class Service>
 
  240  static_assert(std::is_base_of<execution_context::service, Key>::value,
 
  241                "Key must derive from execution_context::service");
 
  242  static_assert(std::is_base_of<Key, Service>::value,
 
  243                "Service must derive from Key");
 
  245  auto key = execution_context::service_key<Key>();
 
  250  if (svc == 
nullptr) {
 
  255  return static_cast<Key &
>(*svc);
 
  258template <
class Service, 
class... Args>
 
  262  static_assert(std::is_base_of<execution_context::service, Key>::value,
 
  263                "Key must derive from execution_context::service");
 
  264  static_assert(std::is_base_of<Key, Service>::value,
 
  265                "Service must derive from Key");
 
  267  auto key = execution_context::service_key<Key>();
 
  271  if (svc == 
nullptr) {
 
  273    svc = ctx.
add_service<Service>(std::forward(args)...);
 
  276        "can't make_service(), Service already exists");
 
  279  return static_cast<Service &
>(*svc);
 
  282template <
class Service>
 
  286  std::lock_guard<std::mutex> lk(ctx.services_mtx_);
 
  287  return ctx.keys_.count(execution_context::service_key<Key>()) > 0;
 
  311template <
class T, 
class = std::
void_t<>>
 
  329template <
class T, 
typename U = std::remove_const_t<T>>
 
  331                           void (*f)() = 
nullptr,
 
  332                           const std::allocator<int> &a = {})
 
  335            std::is_copy_constructible<T>,
 
  337            std::is_same<
decltype(*__const_x == *__const_x), 
bool>,
 
  338            std::is_same<
decltype(*__const_x != *__const_x), 
bool>,
 
  339            std::is_void<
decltype(__x->on_work_started())>,
 
  340            std::is_void<
decltype(__x->on_work_finished())>,
 
  341            std::is_void<
decltype(__x->dispatch(std::move(f), a))>,
 
  342            std::is_void<
decltype(__x->post(std::move(f), a))>,
 
  343            std::is_void<
decltype(__x->defer(std::move(f), a))>>::value,
 
  346        std::void_t<
decltype(__x->context()), 
void()>>;
 
  367template <
class T, 
class Executor, 
typename = std::
void_t<>>
 
  370template <
class T, 
class Executor>
 
  372    : std::is_convertible<Executor, typename T::executor_type> {};
 
  376template <
class T, 
class Executor>
 
  379template <
class T, 
class Executor>
 
  383template <
class T, 
class Executor, 
typename = std::
void_t<>>
 
  387  static type __get(
const T & , 
const Executor &ex) 
noexcept {
 
  392template <
class T, 
class Executor>
 
  394                                std::void_t<typename T::executor_type>> {
 
  395  using type = 
typename T::executor_type;
 
  397  static type __get(
const T &t, 
const Executor & ) 
noexcept {
 
  398    return t.get_executor();
 
  402template <
class T, 
class Executor = system_executor>
 
  403struct associated_executor;
 
  405template <
class T, 
class Executor = system_executor>
 
  408template <
class T, 
class Executor>
 
  410  static auto get(
const T &t, 
const Executor &ex = Executor()) noexcept {
 
  412    return Impl::__get(t, ex);
 
  420template <
class T, 
class Executor>
 
  422    const T &t, 
const Executor &ex) 
noexcept;
 
  424template <
class T, 
class ExecutorContext>
 
  425associated_executor_t<T, typename ExecutorContext::executor_type>
 
  433template <
class T, 
class Executor>
 
  435    const T &t, 
const Executor &ex) 
noexcept {
 
  439template <
class T, 
class ExecutorContext>
 
  440associated_executor_t<T, typename ExecutorContext::executor_type>
 
  451template <
class Executor>
 
  458    ex_.on_work_started();
 
  461      : 
ex_{other.ex_}, 
owns_{other.owns_} {
 
  463      ex_.on_work_started();
 
  467      : 
ex_{std::move(other.ex_)}, 
owns_{std::exchange(other.owns_, 
false)} {}
 
  473      ex_.on_work_finished();
 
  483      ex_.on_work_finished();
 
  495template <
class Executor>
 
  497  requires(is_executor_v<Executor>)
 
  502template <
class ExecutionContext>
 
  505  requires(std::is_convertible_v<ExecutionContext &, execution_context &>)
 
  512  requires(!is_executor_v<T> &&
 
  513           !std::is_convertible_v<T &, execution_context &>)
 
  519template <
class T, 
class U>
 
  522                                                        std::forward<U>(u)))) {
 
  538  template <
class Func, 
class ProtoAllocator>
 
  539  void dispatch(Func &&f, 
const ProtoAllocator &a) 
const;
 
  540  template <
class Func, 
class ProtoAllocator>
 
  541  void post(Func &&f, 
const ProtoAllocator &a) 
const;
 
  542  template <
class Func, 
class ProtoAllocator>
 
  543  void defer(Func &&f, 
const ProtoAllocator &a) 
const;
 
  574    std::lock_guard<std::mutex> lk(
mtx_);
 
  580    std::lock_guard<std::mutex> lk(
mtx_);
 
  595      std::function<void()> f;
 
  597        std::unique_lock<std::mutex> lk(
mtx_);
 
  603        f = std::move(
tasks_.front());
 
  610  void post_(std::function<
void()> f) {
 
  611    std::lock_guard<std::mutex> lk(
mtx_);
 
  618    tasks_.push(std::move(f));
 
  630  std::condition_variable 
cv_;
 
  641template <
class Func, 
class ProtoAllocator>
 
  646template <
class Func, 
class ProtoAllocator>
 
  648  std::decay_t<Func>{std::forward<Func>(f)}();
 
  650template <
class Func, 
class ProtoAllocator>
 
  652  post(std::forward<Func>(f), a);
 
  664template <
class CompletionHandler>
 
  684template <
class CompletionHandler>
 
  692template <
class CompletionToken>
 
  706template <
class Executor, 
class CompletionToken>
 
  707typename async_result<std::decay_t<CompletionToken>, void()>::return_type
 
  708dispatch(
const Executor &ex, CompletionToken &&token)
 
  709  requires(is_executor_v<Executor>)
 
  723template <
class ExecutionContext, 
class CompletionToken>
 
  724typename async_result<std::decay_t<CompletionToken>, void()>::return_type
 
  726  requires(std::is_convertible_v<ExecutionContext &, execution_context &>)
 
  729                       std::forward<CompletionToken>(token));
 
  737template <
class CompletionToken>
 
  738auto post(CompletionToken &&token) {
 
  751template <
class Executor, 
class CompletionToken>
 
  752typename async_result<std::decay_t<CompletionToken>, void()>::return_type  
 
  753post(
const Executor &ex, CompletionToken &&token)
 
  754  requires(is_executor_v<Executor>)
 
  768template <
class ExecutionContext, 
class CompletionToken>
 
  769typename async_result<std::decay_t<CompletionToken>, void()>::return_type  
 
  771  requires(std::is_convertible_v<ExecutionContext &, execution_context &>)
 
  773  return net::post(ctx.get_executor(), std::forward<CompletionToken>(token));
 
  778template <
class CompletionToken>
 
  779auto defer(CompletionToken &&token) {
 
  792template <
class Executor, 
class CompletionToken>
 
  793typename async_result<std::decay_t<CompletionToken>, void()>::return_type  
 
  794defer(
const Executor &ex, CompletionToken &&token)
 
  795  requires(is_executor_v<Executor>)
 
  809template <
class ExecutionContext, 
class CompletionToken>
 
  810typename async_result<std::decay_t<CompletionToken>, void()>::return_type  
 
  812  requires(std::is_convertible_v<ExecutionContext &, execution_context &>)
 
  814  return net::defer(ctx.get_executor(), std::forward<CompletionToken>(token));
 
  819template <
class Executor>
 
  828  template <
class ProtoAllocator>
 
  829  strand(std::allocator_arg_t, 
const ProtoAllocator & , Executor ex)
 
  835  template <
class OtherExecutor>
 
  838  template <
class OtherExecutor>
 
  840      : 
inner_ex_{std::move(other.inner_ex_)} {}
 
  854  template <
class OtherExecutor>
 
  861  template <
class OtherExecutor>
 
  883  template <
class Func, 
class ProtoAllocator>
 
  884  void dispatch(Func &&f, 
const ProtoAllocator & )
 const {
 
  886      std::forward<Func>(f)();
 
  889  template <
class Func, 
class ProtoAllocator>
 
  890  void post(Func &&f, 
const ProtoAllocator &a) 
const;
 
  891  template <
class Func, 
class ProtoAllocator>
 
  892  void defer(Func &&f, 
const ProtoAllocator &a) 
const;
 
  901template <
class Executor>
 
  904template <
class Executor>
 
  918                  [e](
auto &svc) { svc.ptr_->notify_fork(e); });
 
  921                  [e](
auto &svc) { svc.ptr_->notify_fork(e); });
 
  930      svc.ptr_->shutdown();
 
execution context for SQL.
Definition: sql_exec_context.h:39
 
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4571
 
Definition: executor.h:72
 
std::conditional_t< std::is_same< CompletionToken, completion_handler_type >::value, completion_handler_type &, completion_handler_type > handler_type
Definition: executor.h:81
 
async_completion & operator=(const async_completion &)=delete
 
handler_type completion_handler
Definition: executor.h:90
 
async_completion(CompletionToken &t)
Definition: executor.h:84
 
async_completion(const async_completion &)=delete
 
result_type result
Definition: executor.h:91
 
typename result_type::completion_handler_type completion_handler_type
Definition: executor.h:76
 
Definition: executor.h:55
 
void return_type
Definition: executor.h:58
 
CompletionToken completion_handler_type
Definition: executor.h:57
 
return_type get()
Definition: executor.h:64
 
async_result(const async_result &)=delete
 
async_result(completion_handler_type &)
Definition: executor.h:60
 
async_result & operator=(const async_result &)=delete
 
Definition: executor.h:291
 
virtual ~service()=default
 
virtual void shutdown() noexcept=0
 
service(const service &)=delete
 
service & operator=(const service &)=delete
 
service(execution_context &owner)
Definition: executor.h:293
 
execution_context & context_
Definition: executor.h:304
 
virtual void notify_fork(fork_event) noexcept
Definition: executor.h:301
 
execution_context & context() noexcept
Definition: executor.h:297
 
Definition: executor.h:154
 
friend bool has_service(const execution_context &ctx) noexcept
Definition: executor.h:283
 
service * add_service(Args &&...args)
Definition: executor.h:218
 
std::list< ServicePtr > services_
Definition: executor.h:214
 
execution_context(const execution_context &)=delete
 
void shutdown() noexcept
Definition: executor.h:926
 
void destroy() noexcept
Definition: executor.h:176
 
static void service_deleter(service *svc)
Definition: executor.h:186
 
friend Service & make_service(execution_context &ctx, Args &&...args)
Definition: executor.h:259
 
void notify_fork(fork_event e)
Definition: executor.h:914
 
execution_context()=default
 
execution_context & operator=(const execution_context &)=delete
 
virtual ~execution_context()
Definition: executor.h:164
 
static service_key_type service_key()
maps selected type to unique identifier.
Definition: executor.h:206
 
std::mutex services_mtx_
Definition: executor.h:211
 
friend Service::key_type & use_service(execution_context &ctx)
Definition: executor.h:237
 
std::type_index service_key_type
Definition: executor.h:200
 
std::unordered_map< service_key_type, service * > keys_
Definition: executor.h:215
 
Definition: executor.h:452
 
Executor executor_type
Definition: executor.h:454
 
executor_work_guard(const executor_work_guard &other) noexcept
Definition: executor.h:460
 
bool owns_
Definition: executor.h:490
 
executor_type get_executor() const noexcept
Definition: executor.h:477
 
executor_work_guard(executor_work_guard &&other) noexcept
Definition: executor.h:466
 
void reset() noexcept
Definition: executor.h:481
 
Executor ex_
Definition: executor.h:489
 
executor_work_guard(const executor_type &ex) noexcept
Definition: executor.h:456
 
executor_work_guard & operator=(const executor_work_guard &other)=delete
 
~executor_work_guard()
Definition: executor.h:471
 
bool owns_work() const noexcept
Definition: executor.h:479
 
static constexpr Value * contains(const Key *k)
check if a callstack contains a pointer already.
Definition: callstack.h:151
 
function object for net::dispatch(), net::post(), net::defer().
Definition: executor.h:665
 
Dispatcher(CompletionHandler &handler)
Definition: executor.h:667
 
decltype(net::make_work_guard(handler_)) work_guard_
Definition: executor.h:681
 
CompletionHandler handler_
Definition: executor.h:680
 
void operator()()
Definition: executor.h:671
 
Definition: executor.h:149
 
Definition: executor.h:820
 
void post(Func &&f, const ProtoAllocator &a) const
 
strand(Executor ex)
Definition: executor.h:826
 
strand operator=(const strand< OtherExecutor > &other) noexcept
Definition: executor.h:855
 
strand(strand< OtherExecutor > &&other) noexcept
Definition: executor.h:839
 
strand(const strand< OtherExecutor > &other) noexcept
Definition: executor.h:836
 
Executor inner_ex_
Definition: executor.h:895
 
bool running_in_this_thread() const noexcept
Definition: executor.h:874
 
void defer(Func &&f, const ProtoAllocator &a) const
 
strand operator=(strand< OtherExecutor > &&other) noexcept
Definition: executor.h:862
 
strand operator=(strand &&other) noexcept
Definition: executor.h:848
 
void on_work_started() const noexcept
Definition: executor.h:880
 
void on_work_finished() const noexcept
Definition: executor.h:881
 
void dispatch(Func &&f, const ProtoAllocator &) const
Definition: executor.h:884
 
execution_context & context() const noexcept
Definition: executor.h:878
 
Executor inner_executor_type
Definition: executor.h:822
 
strand(strand &&other) noexcept
Definition: executor.h:833
 
strand operator=(const strand &other) noexcept
Definition: executor.h:842
 
std::queue< std::function< void()> > jobs_
Definition: executor.h:898
 
strand(std::allocator_arg_t, const ProtoAllocator &, Executor ex)
Definition: executor.h:829
 
strand(const strand &other) noexcept
Definition: executor.h:832
 
inner_executor_type get_inner_executor() const noexcept
Definition: executor.h:872
 
bool running_
Definition: executor.h:897
 
Definition: executor.h:559
 
static system_context & get_() noexcept
Definition: executor.h:623
 
bool stopped_
Definition: executor.h:632
 
void join()
Definition: executor.h:583
 
std::condition_variable cv_
Definition: executor.h:630
 
std::queue< std::function< void()> > tasks_
Definition: executor.h:631
 
void run_()
Definition: executor.h:593
 
std::thread thread_
Definition: executor.h:628
 
system_context(const system_context &)=delete
 
bool stopped() const noexcept
Definition: executor.h:579
 
~system_context() override
Definition: executor.h:566
 
void post_(std::function< void()> f)
Definition: executor.h:610
 
std::mutex mtx_
Definition: executor.h:629
 
friend class system_executor
Definition: executor.h:591
 
executor_type get_executor() noexcept
Definition: executor.h:571
 
system_context & operator=(const system_context &)=delete
 
void stop()
Definition: executor.h:573
 
system_context(__tag)
Definition: executor.h:589
 
Definition: executor.h:529
 
system_executor()=default
 
void dispatch(Func &&f, const ProtoAllocator &a) const
Definition: executor.h:647
 
void defer(Func &&f, const ProtoAllocator &a) const
Definition: executor.h:651
 
void on_work_finished() const noexcept
Definition: executor.h:536
 
system_context & context() const noexcept
Definition: executor.h:637
 
void on_work_started() const noexcept
Definition: executor.h:535
 
void post(Func &&f, const ProtoAllocator &a) const
Definition: executor.h:642
 
Header for compiler-dependent features.
 
#define MY_COMPILER_DIAGNOSTIC_PUSH()
save the compiler's diagnostic (enabled warnings, errors, ...) state
Definition: my_compiler.h:285
 
#define MY_COMPILER_DIAGNOSTIC_POP()
restore the compiler's diagnostic (enabled warnings, errors, ...) state
Definition: my_compiler.h:286
 
static QUEUE queue
Definition: myisampack.cc:210
 
void for_each(const Shards< COUNT > &shards, Function &&f) noexcept
Iterate over the shards.
Definition: ut0counter.h:323
 
std::string_view Key
The key type for the hash structure in HashJoinRowBuffer.
Definition: hash_join_buffer.h:102
 
int key_type
Definition: method.h:38
 
Definition: http_server_component.cc:34
 
auto executor_requirements(U *__x=nullptr, const U *__const_x=nullptr, void(*f)()=nullptr, const std::allocator< int > &a={}) -> std::enable_if_t< std::conjunction< std::is_copy_constructible< T >, std::is_same< decltype(*__const_x== *__const_x), bool >, std::is_same< decltype(*__const_x != *__const_x), bool >, std::is_void< decltype(__x->on_work_started())>, std::is_void< decltype(__x->on_work_finished())>, std::is_void< decltype(__x->dispatch(std::move(f), a))>, std::is_void< decltype(__x->post(std::move(f), a))>, std::is_void< decltype(__x->defer(std::move(f), a))> >::value, std::void_t< decltype(__x->context()), void()> >
 
Dispatcher< CompletionHandler > make_dispatcher(CompletionHandler &handler)
Definition: executor.h:685
 
constexpr bool uses_executor_v
Definition: executor.h:380
 
bool operator!=(const system_executor &, const system_executor &)
Definition: executor.h:551
 
bool has_service(const execution_context &ctx) noexcept
Definition: executor.h:283
 
auto defer(CompletionToken &&token)
Definition: executor.h:779
 
typename associated_executor< T, Executor >::type associated_executor_t
Definition: executor.h:406
 
executor_work_guard< Executor > make_work_guard(const Executor &ex)
Definition: executor.h:496
 
Service & make_service(execution_context &ctx, Args &&...args)
Definition: executor.h:259
 
associated_allocator_t< T > get_associated_allocator(const T &t) noexcept
Definition: executor.h:138
 
auto dispatch(CompletionToken &&token)
Definition: executor.h:693
 
auto post(CompletionToken &&token)
queue a function call for later execution.
Definition: executor.h:738
 
constexpr executor_arg_t executor_arg
Definition: executor.h:361
 
Service::key_type & use_service(execution_context &ctx)
Definition: executor.h:237
 
typename associated_allocator< T, ProtoAllocator >::type associated_allocator_t
Definition: executor.h:104
 
constexpr bool is_executor_v
Definition: executor.h:356
 
associated_executor_t< T > get_associated_executor(const T &t) noexcept
Definition: executor.h:429
 
bool operator==(const system_executor &, const system_executor &)
Definition: executor.h:547
 
fork_event
Definition: executor.h:48
 
Definition: gcs_xcom_synode.h:64
 
std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > > unique_ptr
The following is a common type that is returned by all the ut::make_unique (non-aligned) specializati...
Definition: ut0new.h:2443
 
MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Winconsistent-missing-destructor-override") static Scope_guard static_guard([]()
Definition: protobuf_plugin.cc:33
 
required string key
Definition: replication_asynchronous_connection_failover.proto:60
 
required string type
Definition: replication_group_member_actions.proto:34
 
static type __get(const T &t, const ProtoAllocator &) noexcept
Definition: executor.h:122
 
typename T::allocator_type type
Definition: executor.h:120
 
Definition: executor.h:109
 
static type __get(const T &, const ProtoAllocator &a) noexcept
Definition: executor.h:112
 
ProtoAllocator type
Definition: executor.h:110
 
Definition: executor.h:128
 
static auto get(const T &t, const ProtoAllocator &a=ProtoAllocator()) noexcept
Definition: executor.h:129
 
static type __get(const T &t, const Executor &) noexcept
Definition: executor.h:397
 
typename T::executor_type type
Definition: executor.h:395
 
Definition: executor.h:384
 
static type __get(const T &, const Executor &ex) noexcept
Definition: executor.h:387
 
Executor type
Definition: executor.h:385
 
Definition: executor.h:409
 
static auto get(const T &t, const Executor &ex=Executor()) noexcept
Definition: executor.h:410
 
Definition: executor.h:190
 
ServicePtr(Service *svc)
Definition: executor.h:192
 
std::unique_ptr< service, void(*)(service *)> ptr_
Definition: executor.h:197
 
bool active_
Definition: executor.h:195
 
Definition: executor.h:359
 
Definition: executor.h:312
 
Definition: executor.h:368
 
Definition: executor.h:353
 
Definition: executor.h:588
 
Definition: executor.h:377