summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/include/asio/cancellation_signal.hpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/include/asio/cancellation_signal.hpp')
-rw-r--r--3rdparty/asio/include/asio/cancellation_signal.hpp359
1 files changed, 359 insertions, 0 deletions
diff --git a/3rdparty/asio/include/asio/cancellation_signal.hpp b/3rdparty/asio/include/asio/cancellation_signal.hpp
new file mode 100644
index 00000000000..afbaecdaf40
--- /dev/null
+++ b/3rdparty/asio/include/asio/cancellation_signal.hpp
@@ -0,0 +1,359 @@
+//
+// cancellation_signal.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_CANCELLATION_SIGNAL_HPP
+#define ASIO_CANCELLATION_SIGNAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include <cassert>
+#include <new>
+#include <utility>
+#include "asio/cancellation_type.hpp"
+#include "asio/detail/cstddef.hpp"
+#include "asio/detail/thread_context.hpp"
+#include "asio/detail/thread_info_base.hpp"
+#include "asio/detail/type_traits.hpp"
+#include "asio/detail/variadic_templates.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+class cancellation_handler_base
+{
+public:
+ virtual void call(cancellation_type_t) = 0;
+ virtual std::pair<void*, std::size_t> destroy() ASIO_NOEXCEPT = 0;
+
+protected:
+ ~cancellation_handler_base() {}
+};
+
+template <typename Handler>
+class cancellation_handler
+ : public cancellation_handler_base
+{
+public:
+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)
+ template <typename... Args>
+ cancellation_handler(std::size_t size, ASIO_MOVE_ARG(Args)... args)
+ : handler_(ASIO_MOVE_CAST(Args)(args)...),
+ size_(size)
+ {
+ }
+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+ cancellation_handler(std::size_t size)
+ : handler_(),
+ size_(size)
+ {
+ }
+
+#define ASIO_PRIVATE_HANDLER_CTOR_DEF(n) \
+ template <ASIO_VARIADIC_TPARAMS(n)> \
+ cancellation_handler(std::size_t size, ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ : handler_(ASIO_VARIADIC_MOVE_ARGS(n)), \
+ size_(size) \
+ { \
+ } \
+ /**/
+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_HANDLER_CTOR_DEF)
+#undef ASIO_PRIVATE_HANDLER_CTOR_DEF
+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+ void call(cancellation_type_t type)
+ {
+ handler_(type);
+ }
+
+ std::pair<void*, std::size_t> destroy() ASIO_NOEXCEPT
+ {
+ std::pair<void*, std::size_t> mem(this, size_);
+ this->cancellation_handler::~cancellation_handler();
+ return mem;
+ }
+
+ Handler& handler() ASIO_NOEXCEPT
+ {
+ return handler_;
+ }
+
+private:
+ ~cancellation_handler()
+ {
+ }
+
+ Handler handler_;
+ std::size_t size_;
+};
+
+} // namespace detail
+
+class cancellation_slot;
+
+/// A cancellation signal with a single slot.
+class cancellation_signal
+{
+public:
+ ASIO_CONSTEXPR cancellation_signal()
+ : handler_(0)
+ {
+ }
+
+ ~cancellation_signal()
+ {
+ if (handler_)
+ {
+ std::pair<void*, std::size_t> mem = handler_->destroy();
+ detail::thread_info_base::deallocate(
+ detail::thread_info_base::cancellation_signal_tag(),
+ detail::thread_context::top_of_thread_call_stack(),
+ mem.first, mem.second);
+ }
+ }
+
+ /// Emits the signal and causes invocation of the slot's handler, if any.
+ void emit(cancellation_type_t type)
+ {
+ if (handler_)
+ handler_->call(type);
+ }
+
+ /// Returns the single slot associated with the signal.
+ /**
+ * The signal object must remain valid for as long the slot may be used.
+ * Destruction of the signal invalidates the slot.
+ */
+ cancellation_slot slot() ASIO_NOEXCEPT;
+
+private:
+ cancellation_signal(const cancellation_signal&) ASIO_DELETED;
+ cancellation_signal& operator=(const cancellation_signal&) ASIO_DELETED;
+
+ detail::cancellation_handler_base* handler_;
+};
+
+/// A slot associated with a cancellation signal.
+class cancellation_slot
+{
+public:
+ /// Creates a slot that is not connected to any cancellation signal.
+ ASIO_CONSTEXPR cancellation_slot()
+ : handler_(0)
+ {
+ }
+
+#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \
+ || defined(GENERATING_DOCUMENTATION)
+ /// Installs a handler into the slot, constructing the new object directly.
+ /**
+ * Destroys any existing handler in the slot, then installs the new handler,
+ * constructing it with the supplied @c args.
+ *
+ * The handler is a function object to be called when the signal is emitted.
+ * The signature of the handler must be
+ * @code void handler(asio::cancellation_type_t); @endcode
+ *
+ * @param args Arguments to be passed to the @c CancellationHandler object's
+ * constructor.
+ *
+ * @returns A reference to the newly installed handler.
+ *
+ * @note Handlers installed into the slot via @c emplace are not required to
+ * be copy constructible or move constructible.
+ */
+ template <typename CancellationHandler, typename... Args>
+ CancellationHandler& emplace(ASIO_MOVE_ARG(Args)... args)
+ {
+ typedef detail::cancellation_handler<CancellationHandler>
+ cancellation_handler_type;
+ auto_delete_helper del = { prepare_memory(
+ sizeof(cancellation_handler_type),
+ ASIO_ALIGNOF(CancellationHandler)) };
+ cancellation_handler_type* handler_obj =
+ new (del.mem.first) cancellation_handler_type(
+ del.mem.second, ASIO_MOVE_CAST(Args)(args)...);
+ del.mem.first = 0;
+ *handler_ = handler_obj;
+ return handler_obj->handler();
+ }
+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+ // || defined(GENERATING_DOCUMENTATION)
+ template <typename CancellationHandler>
+ CancellationHandler& emplace()
+ {
+ typedef detail::cancellation_handler<CancellationHandler>
+ cancellation_handler_type;
+ auto_delete_helper del = { prepare_memory(
+ sizeof(cancellation_handler_type),
+ ASIO_ALIGNOF(CancellationHandler)) };
+ cancellation_handler_type* handler_obj =
+ new (del.mem.first) cancellation_handler_type(del.mem.second);
+ del.mem.first = 0;
+ *handler_ = handler_obj;
+ return handler_obj->handler();
+ }
+
+#define ASIO_PRIVATE_HANDLER_EMPLACE_DEF(n) \
+ template <typename CancellationHandler, ASIO_VARIADIC_TPARAMS(n)> \
+ CancellationHandler& emplace(ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ typedef detail::cancellation_handler<CancellationHandler> \
+ cancellation_handler_type; \
+ auto_delete_helper del = { prepare_memory( \
+ sizeof(cancellation_handler_type), \
+ ASIO_ALIGNOF(CancellationHandler)) }; \
+ cancellation_handler_type* handler_obj = \
+ new (del.mem.first) cancellation_handler_type( \
+ del.mem.second, ASIO_VARIADIC_MOVE_ARGS(n)); \
+ del.mem.first = 0; \
+ *handler_ = handler_obj; \
+ return handler_obj->handler(); \
+ } \
+ /**/
+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_HANDLER_EMPLACE_DEF)
+#undef ASIO_PRIVATE_HANDLER_EMPLACE_DEF
+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
+
+ /// Installs a handler into the slot.
+ /**
+ * Destroys any existing handler in the slot, then installs the new handler,
+ * constructing it as a decay-copy of the supplied handler.
+ *
+ * The handler is a function object to be called when the signal is emitted.
+ * The signature of the handler must be
+ * @code void handler(asio::cancellation_type_t); @endcode
+ *
+ * @param handler The handler to be installed.
+ *
+ * @returns A reference to the newly installed handler.
+ */
+ template <typename CancellationHandler>
+ typename decay<CancellationHandler>::type& assign(
+ ASIO_MOVE_ARG(CancellationHandler) handler)
+ {
+ return this->emplace<typename decay<CancellationHandler>::type>(
+ ASIO_MOVE_CAST(CancellationHandler)(handler));
+ }
+
+ /// Clears the slot.
+ /**
+ * Destroys any existing handler in the slot.
+ */
+ void clear()
+ {
+ if (handler_ != 0 && *handler_ != 0)
+ {
+ std::pair<void*, std::size_t> mem = (*handler_)->destroy();
+ detail::thread_info_base::deallocate(
+ detail::thread_info_base::cancellation_signal_tag(),
+ detail::thread_context::top_of_thread_call_stack(),
+ mem.first, mem.second);
+ *handler_ = 0;
+ }
+ }
+
+ /// Returns whether the slot is connected to a signal.
+ ASIO_CONSTEXPR bool is_connected() const ASIO_NOEXCEPT
+ {
+ return handler_ != 0;
+ }
+
+ /// Returns whether the slot is connected and has an installed handler.
+ ASIO_CONSTEXPR bool has_handler() const ASIO_NOEXCEPT
+ {
+ return handler_ != 0 && *handler_ != 0;
+ }
+
+ /// Compare two slots for equality.
+ friend ASIO_CONSTEXPR bool operator==(const cancellation_slot& lhs,
+ const cancellation_slot& rhs) ASIO_NOEXCEPT
+ {
+ return lhs.handler_ == rhs.handler_;
+ }
+
+ /// Compare two slots for inequality.
+ friend ASIO_CONSTEXPR bool operator!=(const cancellation_slot& lhs,
+ const cancellation_slot& rhs) ASIO_NOEXCEPT
+ {
+ return lhs.handler_ != rhs.handler_;
+ }
+
+private:
+ friend class cancellation_signal;
+
+ ASIO_CONSTEXPR cancellation_slot(int,
+ detail::cancellation_handler_base** handler)
+ : handler_(handler)
+ {
+ }
+
+ std::pair<void*, std::size_t> prepare_memory(
+ std::size_t size, std::size_t align)
+ {
+ assert(handler_);
+ std::pair<void*, std::size_t> mem;
+ if (*handler_)
+ {
+ mem = (*handler_)->destroy();
+ *handler_ = 0;
+ }
+ if (size > mem.second
+ || reinterpret_cast<std::size_t>(mem.first) % align != 0)
+ {
+ if (mem.first)
+ {
+ detail::thread_info_base::deallocate(
+ detail::thread_info_base::cancellation_signal_tag(),
+ detail::thread_context::top_of_thread_call_stack(),
+ mem.first, mem.second);
+ }
+ mem.first = detail::thread_info_base::allocate(
+ detail::thread_info_base::cancellation_signal_tag(),
+ detail::thread_context::top_of_thread_call_stack(),
+ size, align);
+ mem.second = size;
+ }
+ return mem;
+ }
+
+ struct auto_delete_helper
+ {
+ std::pair<void*, std::size_t> mem;
+
+ ~auto_delete_helper()
+ {
+ if (mem.first)
+ {
+ detail::thread_info_base::deallocate(
+ detail::thread_info_base::cancellation_signal_tag(),
+ detail::thread_context::top_of_thread_call_stack(),
+ mem.first, mem.second);
+ }
+ }
+ };
+
+ detail::cancellation_handler_base** handler_;
+};
+
+inline cancellation_slot cancellation_signal::slot() ASIO_NOEXCEPT
+{
+ return cancellation_slot(0, &handler_);
+}
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_CANCELLATION_SIGNAL_HPP