chaiscript_threading.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // This file is distributed under the BSD License.
  2. // See "license.txt" for details.
  3. // Copyright 2009-2012, Jonathan Turner ([email protected])
  4. // Copyright 2009-2017, Jason Turner ([email protected])
  5. // http://www.chaiscript.com
  6. // This is an open source non-commercial project. Dear PVS-Studio, please check it.
  7. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
  8. #ifndef CHAISCRIPT_THREADING_HPP_
  9. #define CHAISCRIPT_THREADING_HPP_
  10. #include <unordered_map>
  11. #ifndef CHAISCRIPT_NO_THREADS
  12. #include <thread>
  13. #include <mutex>
  14. #else
  15. #ifndef CHAISCRIPT_NO_THREADS_WARNING
  16. #pragma message ("ChaiScript is compiling without thread safety.")
  17. #endif
  18. #endif
  19. #include "chaiscript_defines.hpp"
  20. /// \file
  21. ///
  22. /// This file contains code necessary for thread support in ChaiScript.
  23. /// If the compiler definition CHAISCRIPT_NO_THREADS is defined then thread safety
  24. /// is disabled in ChaiScript. This has the result that some code is faster, because mutex locks are not required.
  25. /// It also has the side effect that the chaiscript::ChaiScript object may not be accessed from more than
  26. /// one thread simultaneously.
  27. namespace chaiscript
  28. {
  29. namespace detail
  30. {
  31. /// If threading is enabled, then this namespace contains std thread classes.
  32. /// If threading is not enabled, then stubbed in wrappers that do nothing are provided.
  33. /// This allows us to avoid \#ifdef code in the sections that need thread safety.
  34. namespace threading
  35. {
  36. #ifndef CHAISCRIPT_NO_THREADS
  37. template<typename T>
  38. using unique_lock = std::unique_lock<T>;
  39. template<typename T>
  40. using shared_lock = std::unique_lock<T>;
  41. template<typename T>
  42. using lock_guard = std::lock_guard<T>;
  43. using shared_mutex = std::mutex;
  44. using std::mutex;
  45. using std::recursive_mutex;
  46. /// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. If
  47. /// threading is not enabled, the class always returns the same data, regardless of which thread it is called from.
  48. template<typename T>
  49. class Thread_Storage
  50. {
  51. public:
  52. Thread_Storage() = default;
  53. Thread_Storage(const Thread_Storage &) = delete;
  54. Thread_Storage(Thread_Storage &&) = delete;
  55. Thread_Storage &operator=(const Thread_Storage &) = delete;
  56. Thread_Storage &operator=(Thread_Storage &&) = delete;
  57. ~Thread_Storage()
  58. {
  59. t().erase(this);
  60. }
  61. inline const T *operator->() const
  62. {
  63. return &(t()[this]);
  64. }
  65. inline const T &operator*() const
  66. {
  67. return t()[this];
  68. }
  69. inline T *operator->()
  70. {
  71. return &(t()[this]);
  72. }
  73. inline T &operator*()
  74. {
  75. return t()[this];
  76. }
  77. void *m_key;
  78. private:
  79. static std::unordered_map<const void*, T> &t()
  80. {
  81. thread_local std::unordered_map<const void *, T> my_t;
  82. return my_t;
  83. }
  84. };
  85. #else // threading disabled
  86. template<typename T>
  87. class unique_lock
  88. {
  89. public:
  90. explicit unique_lock(T &) {}
  91. void lock() {}
  92. void unlock() {}
  93. };
  94. template<typename T>
  95. class shared_lock
  96. {
  97. public:
  98. explicit shared_lock(T &) {}
  99. void lock() {}
  100. void unlock() {}
  101. };
  102. template<typename T>
  103. class lock_guard
  104. {
  105. public:
  106. explicit lock_guard(T &) {}
  107. };
  108. class shared_mutex { };
  109. class recursive_mutex {};
  110. template<typename T>
  111. class Thread_Storage
  112. {
  113. public:
  114. explicit Thread_Storage()
  115. {
  116. }
  117. inline T *operator->() const
  118. {
  119. return &obj;
  120. }
  121. inline T &operator*() const
  122. {
  123. return obj;
  124. }
  125. private:
  126. mutable T obj;
  127. };
  128. #endif
  129. }
  130. }
  131. }
  132. #endif