ThreadLocal.h 3.1 KB

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