Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
2.8KB

  1. //
  2. // detail/call_stack.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_DETAIL_CALL_STACK_HPP
  11. #define ASIO_DETAIL_CALL_STACK_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/detail/noncopyable.hpp"
  17. #include "asio/detail/tss_ptr.hpp"
  18. #include "asio/detail/push_options.hpp"
  19. namespace asio {
  20. namespace detail {
  21. // Helper class to determine whether or not the current thread is inside an
  22. // invocation of io_context::run() for a specified io_context object.
  23. template <typename Key, typename Value = unsigned char>
  24. class call_stack
  25. {
  26. public:
  27. // Context class automatically pushes the key/value pair on to the stack.
  28. class context
  29. : private noncopyable
  30. {
  31. public:
  32. // Push the key on to the stack.
  33. explicit context(Key* k)
  34. : key_(k),
  35. next_(call_stack<Key, Value>::top_)
  36. {
  37. value_ = reinterpret_cast<unsigned char*>(this);
  38. call_stack<Key, Value>::top_ = this;
  39. }
  40. // Push the key/value pair on to the stack.
  41. context(Key* k, Value& v)
  42. : key_(k),
  43. value_(&v),
  44. next_(call_stack<Key, Value>::top_)
  45. {
  46. call_stack<Key, Value>::top_ = this;
  47. }
  48. // Pop the key/value pair from the stack.
  49. ~context()
  50. {
  51. call_stack<Key, Value>::top_ = next_;
  52. }
  53. // Find the next context with the same key.
  54. Value* next_by_key() const
  55. {
  56. context* elem = next_;
  57. while (elem)
  58. {
  59. if (elem->key_ == key_)
  60. return elem->value_;
  61. elem = elem->next_;
  62. }
  63. return 0;
  64. }
  65. private:
  66. friend class call_stack<Key, Value>;
  67. // The key associated with the context.
  68. Key* key_;
  69. // The value associated with the context.
  70. Value* value_;
  71. // The next element in the stack.
  72. context* next_;
  73. };
  74. friend class context;
  75. // Determine whether the specified owner is on the stack. Returns address of
  76. // key if present, 0 otherwise.
  77. static Value* contains(Key* k)
  78. {
  79. context* elem = top_;
  80. while (elem)
  81. {
  82. if (elem->key_ == k)
  83. return elem->value_;
  84. elem = elem->next_;
  85. }
  86. return 0;
  87. }
  88. // Obtain the value at the top of the stack.
  89. static Value* top()
  90. {
  91. context* elem = top_;
  92. return elem ? elem->value_ : 0;
  93. }
  94. private:
  95. // The top of the stack of calls for the current thread.
  96. static tss_ptr<context> top_;
  97. };
  98. template <typename Key, typename Value>
  99. tss_ptr<typename call_stack<Key, Value>::context>
  100. call_stack<Key, Value>::top_;
  101. } // namespace detail
  102. } // namespace asio
  103. #include "asio/detail/pop_options.hpp"
  104. #endif // ASIO_DETAIL_CALL_STACK_HPP