Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:37

0001 //
0002 // detail/call_stack.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_CALL_STACK_HPP
0012 #define BOOST_ASIO_DETAIL_CALL_STACK_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/noncopyable.hpp>
0020 #include <boost/asio/detail/tss_ptr.hpp>
0021 
0022 #include <boost/asio/detail/push_options.hpp>
0023 
0024 namespace boost {
0025 namespace asio {
0026 namespace detail {
0027 
0028 // Helper class to determine whether or not the current thread is inside an
0029 // invocation of io_context::run() for a specified io_context object.
0030 template <typename Key, typename Value = unsigned char>
0031 class call_stack
0032 {
0033 public:
0034   // Context class automatically pushes the key/value pair on to the stack.
0035   class context
0036     : private noncopyable
0037   {
0038   public:
0039     // Push the key on to the stack.
0040     explicit context(Key* k)
0041       : key_(k),
0042         next_(call_stack<Key, Value>::top_)
0043     {
0044       value_ = reinterpret_cast<unsigned char*>(this);
0045       call_stack<Key, Value>::top_ = this;
0046     }
0047 
0048     // Push the key/value pair on to the stack.
0049     context(Key* k, Value& v)
0050       : key_(k),
0051         value_(&v),
0052         next_(call_stack<Key, Value>::top_)
0053     {
0054       call_stack<Key, Value>::top_ = this;
0055     }
0056 
0057     // Pop the key/value pair from the stack.
0058     ~context()
0059     {
0060       call_stack<Key, Value>::top_ = next_;
0061     }
0062 
0063     // Find the next context with the same key.
0064     Value* next_by_key() const
0065     {
0066       context* elem = next_;
0067       while (elem)
0068       {
0069         if (elem->key_ == key_)
0070           return elem->value_;
0071         elem = elem->next_;
0072       }
0073       return 0;
0074     }
0075 
0076   private:
0077     friend class call_stack<Key, Value>;
0078 
0079     // The key associated with the context.
0080     Key* key_;
0081 
0082     // The value associated with the context.
0083     Value* value_;
0084 
0085     // The next element in the stack.
0086     context* next_;
0087   };
0088 
0089   friend class context;
0090 
0091   // Determine whether the specified owner is on the stack. Returns address of
0092   // key if present, 0 otherwise.
0093   static Value* contains(Key* k)
0094   {
0095     context* elem = top_;
0096     while (elem)
0097     {
0098       if (elem->key_ == k)
0099         return elem->value_;
0100       elem = elem->next_;
0101     }
0102     return 0;
0103   }
0104 
0105   // Obtain the value at the top of the stack.
0106   static Value* top()
0107   {
0108     context* elem = top_;
0109     return elem ? elem->value_ : 0;
0110   }
0111 
0112 private:
0113   // The top of the stack of calls for the current thread.
0114   static tss_ptr<context> top_;
0115 };
0116 
0117 template <typename Key, typename Value>
0118 tss_ptr<typename call_stack<Key, Value>::context>
0119 call_stack<Key, Value>::top_;
0120 
0121 } // namespace detail
0122 } // namespace asio
0123 } // namespace boost
0124 
0125 #include <boost/asio/detail/pop_options.hpp>
0126 
0127 #endif // BOOST_ASIO_DETAIL_CALL_STACK_HPP