123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- //
- // detail/call_stack.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 BOOST_ASIO_DETAIL_CALL_STACK_HPP
- #define BOOST_ASIO_DETAIL_CALL_STACK_HPP
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <boost/asio/detail/config.hpp>
- #include <boost/asio/detail/noncopyable.hpp>
- #include <boost/asio/detail/tss_ptr.hpp>
- #include <boost/asio/detail/push_options.hpp>
- namespace boost {
- namespace asio {
- namespace detail {
- // Helper class to determine whether or not the current thread is inside an
- // invocation of io_context::run() for a specified io_context object.
- template <typename Key, typename Value = unsigned char>
- class call_stack
- {
- public:
- // Context class automatically pushes the key/value pair on to the stack.
- class context
- : private noncopyable
- {
- public:
- // Push the key on to the stack.
- explicit context(Key* k)
- : key_(k),
- next_(call_stack<Key, Value>::top_)
- {
- value_ = reinterpret_cast<unsigned char*>(this);
- call_stack<Key, Value>::top_ = this;
- }
- // Push the key/value pair on to the stack.
- context(Key* k, Value& v)
- : key_(k),
- value_(&v),
- next_(call_stack<Key, Value>::top_)
- {
- call_stack<Key, Value>::top_ = this;
- }
- // Pop the key/value pair from the stack.
- ~context()
- {
- call_stack<Key, Value>::top_ = next_;
- }
- // Find the next context with the same key.
- Value* next_by_key() const
- {
- context* elem = next_;
- while (elem)
- {
- if (elem->key_ == key_)
- return elem->value_;
- elem = elem->next_;
- }
- return 0;
- }
- private:
- friend class call_stack<Key, Value>;
- // The key associated with the context.
- Key* key_;
- // The value associated with the context.
- Value* value_;
- // The next element in the stack.
- context* next_;
- };
- friend class context;
- // Determine whether the specified owner is on the stack. Returns address of
- // key if present, 0 otherwise.
- static Value* contains(Key* k)
- {
- context* elem = top_;
- while (elem)
- {
- if (elem->key_ == k)
- return elem->value_;
- elem = elem->next_;
- }
- return 0;
- }
- // Obtain the value at the top of the stack.
- static Value* top()
- {
- context* elem = top_;
- return elem ? elem->value_ : 0;
- }
- private:
- // The top of the stack of calls for the current thread.
- static tss_ptr<context> top_;
- };
- template <typename Key, typename Value>
- tss_ptr<typename call_stack<Key, Value>::context>
- call_stack<Key, Value>::top_;
- } // namespace detail
- } // namespace asio
- } // namespace boost
- #include <boost/asio/detail/pop_options.hpp>
- #endif // BOOST_ASIO_DETAIL_CALL_STACK_HPP
|