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.

180 lines
4.3 KiB

  1. // -*- C++ -*-
  2. // Copyright (C) 2010, Vaclav Haisman. All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without modifica-
  5. // tion, are permitted provided that the following conditions are met:
  6. //
  7. // 1. Redistributions of source code must retain the above copyright notice,
  8. // this list of conditions and the following disclaimer.
  9. //
  10. // 2. Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. //
  14. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  15. // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  16. // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17. // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  18. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  19. // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  20. // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  21. // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. #ifndef LOG4CPLUS_THREAD_IMPL_TLS_H
  25. #define LOG4CPLUS_THREAD_IMPL_TLS_H
  26. #include <log4cplus/config.hxx>
  27. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  28. #pragma once
  29. #endif
  30. #include <new>
  31. #include <cassert>
  32. #if ! defined (INSIDE_LOG4CPLUS)
  33. # error "This header must not be be used outside log4cplus' implementation files."
  34. #endif
  35. #ifdef LOG4CPLUS_USE_PTHREADS
  36. # include <pthread.h>
  37. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  38. # include <log4cplus/config/windowsh-inc.h>
  39. #elif defined (LOG4CPLUS_SINGLE_THREADED)
  40. # include <vector>
  41. #endif
  42. namespace log4cplus { namespace thread { namespace impl {
  43. typedef void * tls_value_type;
  44. typedef void (* tls_init_cleanup_func_type)(void *);
  45. #ifdef LOG4CPLUS_USE_PTHREADS
  46. typedef pthread_key_t * tls_key_type;
  47. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  48. typedef DWORD tls_key_type;
  49. #elif defined (LOG4CPLUS_SINGLE_THREADED)
  50. typedef std::size_t tls_key_type;
  51. #endif
  52. inline tls_key_type tls_init (tls_init_cleanup_func_type);
  53. inline tls_value_type tls_get_value (tls_key_type);
  54. inline void tls_set_value (tls_key_type, tls_value_type);
  55. inline void tls_cleanup (tls_key_type);
  56. #if defined (LOG4CPLUS_USE_PTHREADS)
  57. tls_key_type
  58. tls_init (tls_init_cleanup_func_type cleanupfunc)
  59. {
  60. pthread_key_t * key = new pthread_key_t;
  61. pthread_key_create (key, cleanupfunc);
  62. return key;
  63. }
  64. tls_value_type
  65. tls_get_value (tls_key_type key)
  66. {
  67. return pthread_getspecific (*key);
  68. }
  69. void
  70. tls_set_value (tls_key_type key, tls_value_type value)
  71. {
  72. pthread_setspecific(*key, value);
  73. }
  74. void
  75. tls_cleanup (tls_key_type key)
  76. {
  77. pthread_key_delete (*key);
  78. delete key;
  79. }
  80. #elif defined (LOG4CPLUS_USE_WIN32_THREADS)
  81. tls_key_type
  82. tls_init (tls_init_cleanup_func_type)
  83. {
  84. return TlsAlloc ();
  85. }
  86. tls_value_type tls_get_value (tls_key_type k)
  87. {
  88. return TlsGetValue (k);
  89. }
  90. void
  91. tls_set_value (tls_key_type k, tls_value_type value)
  92. {
  93. TlsSetValue (k, value);
  94. }
  95. void
  96. tls_cleanup (tls_key_type k)
  97. {
  98. TlsFree (k);
  99. }
  100. #elif defined (LOG4CPLUS_SINGLE_THREADED)
  101. extern std::vector<tls_value_type> * tls_single_threaded_values;
  102. tls_key_type
  103. tls_init (tls_init_cleanup_func_type)
  104. {
  105. if (! tls_single_threaded_values)
  106. tls_single_threaded_values = new std::vector<tls_value_type>;
  107. tls_key_type key = tls_single_threaded_values->size ();
  108. tls_single_threaded_values->resize (key + 1);
  109. return key;
  110. }
  111. tls_value_type
  112. tls_get_value (tls_key_type k)
  113. {
  114. assert (k < tls_single_threaded_values->size ());
  115. return (*tls_single_threaded_values)[k];
  116. }
  117. void
  118. tls_set_value (tls_key_type k, tls_value_type val)
  119. {
  120. assert (k < tls_single_threaded_values->size ());
  121. (*tls_single_threaded_values)[k] = val;
  122. }
  123. void
  124. tls_cleanup (tls_key_type k)
  125. {
  126. assert (k < tls_single_threaded_values->size ());
  127. (*tls_single_threaded_values)[k] = 0;
  128. }
  129. #endif
  130. } } } // namespace log4cplus { namespace thread { namespace impl {
  131. #endif // LOG4CPLUS_THREAD_IMPL_TLS_H