ThreadLocal.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //
  2. // ThreadLocal.h
  3. //
  4. // Library: Foundation
  5. // Package: Threading
  6. // Module: Thread
  7. //
  8. // Definition of the ThreadLocal template and related classes.
  9. //
  10. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #ifndef Foundation_ThreadLocal_INCLUDED
  16. #define Foundation_ThreadLocal_INCLUDED
  17. #include "Poco/Foundation.h"
  18. #include <map>
  19. namespace Poco {
  20. class Foundation_API TLSAbstractSlot
  21. /// This is the base class for all objects
  22. /// that the ThreadLocalStorage class manages.
  23. {
  24. public:
  25. TLSAbstractSlot();
  26. virtual ~TLSAbstractSlot();
  27. };
  28. template <class C>
  29. class TLSSlot: public TLSAbstractSlot
  30. /// The Slot template wraps another class
  31. /// so that it can be stored in a ThreadLocalStorage
  32. /// object. This class is used internally, and you
  33. /// must not create instances of it yourself.
  34. {
  35. public:
  36. TLSSlot():
  37. _value()
  38. {
  39. }
  40. ~TLSSlot()
  41. {
  42. }
  43. C& value()
  44. {
  45. return _value;
  46. }
  47. private:
  48. TLSSlot(const TLSSlot&);
  49. TLSSlot& operator = (const TLSSlot&);
  50. C _value;
  51. };
  52. class Foundation_API ThreadLocalStorage
  53. /// This class manages the local storage for each thread.
  54. /// Never use this class directly, always use the
  55. /// ThreadLocal template for managing thread local storage.
  56. {
  57. public:
  58. ThreadLocalStorage();
  59. /// Creates the TLS.
  60. ~ThreadLocalStorage();
  61. /// Deletes the TLS.
  62. TLSAbstractSlot*& get(const void* key);
  63. /// Returns the slot for the given key.
  64. static ThreadLocalStorage& current();
  65. /// Returns the TLS object for the current thread
  66. /// (which may also be the main thread).
  67. static void clear();
  68. /// Clears the current thread's TLS object.
  69. /// Does nothing in the main thread.
  70. private:
  71. typedef std::map<const void*, TLSAbstractSlot*> TLSMap;
  72. TLSMap _map;
  73. friend class Thread;
  74. };
  75. template <class C>
  76. class ThreadLocal
  77. /// This template is used to declare type safe thread
  78. /// local variables. It can basically be used like
  79. /// a smart pointer class with the special feature
  80. /// that it references a different object
  81. /// in every thread. The underlying object will
  82. /// be created when it is referenced for the first
  83. /// time.
  84. /// See the NestedDiagnosticContext class for an
  85. /// example how to use this template.
  86. /// Every thread only has access to its own
  87. /// thread local data. There is no way for a thread
  88. /// to access another thread's local data.
  89. {
  90. typedef TLSSlot<C> Slot;
  91. public:
  92. ThreadLocal()
  93. {
  94. }
  95. ~ThreadLocal()
  96. {
  97. }
  98. C* operator -> ()
  99. {
  100. return &get();
  101. }
  102. C& operator * ()
  103. /// "Dereferences" the smart pointer and returns a reference
  104. /// to the underlying data object. The reference can be used
  105. /// to modify the object.
  106. {
  107. return get();
  108. }
  109. C& get()
  110. /// Returns a reference to the underlying data object.
  111. /// The reference can be used to modify the object.
  112. {
  113. TLSAbstractSlot*& p = ThreadLocalStorage::current().get(this);
  114. if (!p) p = new Slot;
  115. return static_cast<Slot*>(p)->value();
  116. }
  117. private:
  118. ThreadLocal(const ThreadLocal&);
  119. ThreadLocal& operator = (const ThreadLocal&);
  120. };
  121. } // namespace Poco
  122. #endif // Foundation_ThreadLocal_INCLUDED