ThreadLocal.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. //
  2. // ThreadLocal.h
  3. //
  4. // $Id: //poco/svn/Foundation/include/Poco/ThreadLocal.h#2 $
  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. // Permission is hereby granted, free of charge, to any person or organization
  16. // obtaining a copy of the software and accompanying documentation covered by
  17. // this license (the "Software") to use, reproduce, display, distribute,
  18. // execute, and transmit the Software, and to prepare derivative works of the
  19. // Software, and to permit third-parties to whom the Software is furnished to
  20. // do so, all subject to the following:
  21. //
  22. // The copyright notices in the Software and this entire statement, including
  23. // the above license grant, this restriction and the following disclaimer,
  24. // must be included in all copies of the Software, in whole or in part, and
  25. // all derivative works of the Software, unless such copies or derivative
  26. // works are solely in the form of machine-executable object code generated by
  27. // a source language processor.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  32. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  33. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  34. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  35. // DEALINGS IN THE SOFTWARE.
  36. //
  37. #ifndef Foundation_ThreadLocal_INCLUDED
  38. #define Foundation_ThreadLocal_INCLUDED
  39. #include "Poco/Foundation.h"
  40. #include <map>
  41. namespace Poco {
  42. class Foundation_API TLSAbstractSlot
  43. /// This is the base class for all objects
  44. /// that the ThreadLocalStorage class manages.
  45. {
  46. public:
  47. TLSAbstractSlot();
  48. virtual ~TLSAbstractSlot();
  49. };
  50. template <class C>
  51. class TLSSlot: public TLSAbstractSlot
  52. /// The Slot template wraps another class
  53. /// so that it can be stored in a ThreadLocalStorage
  54. /// object. This class is used internally, and you
  55. /// must not create instances of it yourself.
  56. {
  57. public:
  58. TLSSlot():
  59. _value()
  60. {
  61. }
  62. ~TLSSlot()
  63. {
  64. }
  65. C& value()
  66. {
  67. return _value;
  68. }
  69. private:
  70. TLSSlot(const TLSSlot&);
  71. TLSSlot& operator = (const TLSSlot&);
  72. C _value;
  73. };
  74. class Foundation_API ThreadLocalStorage
  75. /// This class manages the local storage for each thread.
  76. /// Never use this class directly, always use the
  77. /// ThreadLocal template for managing thread local storage.
  78. {
  79. public:
  80. ThreadLocalStorage();
  81. /// Creates the TLS.
  82. ~ThreadLocalStorage();
  83. /// Deletes the TLS.
  84. TLSAbstractSlot*& get(const void* key);
  85. /// Returns the slot for the given key.
  86. static ThreadLocalStorage& current();
  87. /// Returns the TLS object for the current thread
  88. /// (which may also be the main thread).
  89. static void clear();
  90. /// Clears the current thread's TLS object.
  91. /// Does nothing in the main thread.
  92. private:
  93. typedef std::map<const void*, TLSAbstractSlot*> TLSMap;
  94. TLSMap _map;
  95. friend class Thread;
  96. };
  97. template <class C>
  98. class ThreadLocal
  99. /// This template is used to declare type safe thread
  100. /// local variables. It can basically be used like
  101. /// a smart pointer class with the special feature
  102. /// that it references a different object
  103. /// in every thread. The underlying object will
  104. /// be created when it is referenced for the first
  105. /// time.
  106. /// See the NestedDiagnosticContext class for an
  107. /// example how to use this template.
  108. /// Every thread only has access to its own
  109. /// thread local data. There is no way for a thread
  110. /// to access another thread's local data.
  111. {
  112. typedef TLSSlot<C> Slot;
  113. public:
  114. ThreadLocal()
  115. {
  116. }
  117. ~ThreadLocal()
  118. {
  119. }
  120. C* operator -> ()
  121. {
  122. return &get();
  123. }
  124. C& operator * ()
  125. /// "Dereferences" the smart pointer and returns a reference
  126. /// to the underlying data object. The reference can be used
  127. /// to modify the object.
  128. {
  129. return get();
  130. }
  131. C& get()
  132. /// Returns a reference to the underlying data object.
  133. /// The reference can be used to modify the object.
  134. {
  135. TLSAbstractSlot*& p = ThreadLocalStorage::current().get(this);
  136. if (!p) p = new Slot;
  137. return static_cast<Slot*>(p)->value();
  138. }
  139. private:
  140. ThreadLocal(const ThreadLocal&);
  141. ThreadLocal& operator = (const ThreadLocal&);
  142. };
  143. } // namespace Poco
  144. #endif // Foundation_ThreadLocal_INCLUDED