log4cplus
1.1.0
|
00001 // -*- C++ -*- 00002 // Copyright (C) 2010, Vaclav Haisman. All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without modifica- 00005 // tion, are permitted provided that the following conditions are met: 00006 // 00007 // 1. Redistributions of source code must retain the above copyright notice, 00008 // this list of conditions and the following disclaimer. 00009 // 00010 // 2. Redistributions in binary form must reproduce the above copyright notice, 00011 // this list of conditions and the following disclaimer in the documentation 00012 // and/or other materials provided with the distribution. 00013 // 00014 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 00015 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00016 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00017 // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00018 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- 00019 // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00020 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00021 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00022 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00023 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00024 00025 #ifndef LOG4CPLUS_THREAD_IMPL_TLS_H 00026 #define LOG4CPLUS_THREAD_IMPL_TLS_H 00027 00028 #include <log4cplus/config.hxx> 00029 00030 #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) 00031 #pragma once 00032 #endif 00033 00034 #include <new> 00035 #include <cassert> 00036 00037 #if ! defined (INSIDE_LOG4CPLUS) 00038 # error "This header must not be be used outside log4cplus' implementation files." 00039 #endif 00040 00041 #ifdef LOG4CPLUS_USE_PTHREADS 00042 # include <pthread.h> 00043 00044 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00045 # include <log4cplus/config/windowsh-inc.h> 00046 00047 #elif defined (LOG4CPLUS_SINGLE_THREADED) 00048 # include <vector> 00049 00050 #endif 00051 00052 00053 namespace log4cplus { namespace thread { namespace impl { 00054 00055 00056 typedef void * tls_value_type; 00057 typedef void (* tls_init_cleanup_func_type)(void *); 00058 00059 #ifdef LOG4CPLUS_USE_PTHREADS 00060 typedef pthread_key_t * tls_key_type; 00061 00062 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00063 typedef DWORD tls_key_type; 00064 00065 #elif defined (LOG4CPLUS_SINGLE_THREADED) 00066 typedef std::size_t tls_key_type; 00067 00068 #endif 00069 00070 00071 inline tls_key_type tls_init (tls_init_cleanup_func_type); 00072 inline tls_value_type tls_get_value (tls_key_type); 00073 inline void tls_set_value (tls_key_type, tls_value_type); 00074 inline void tls_cleanup (tls_key_type); 00075 00076 00077 #if defined (LOG4CPLUS_USE_PTHREADS) 00078 tls_key_type 00079 tls_init (tls_init_cleanup_func_type cleanupfunc) 00080 { 00081 pthread_key_t * key = new pthread_key_t; 00082 pthread_key_create (key, cleanupfunc); 00083 return key; 00084 } 00085 00086 00087 tls_value_type 00088 tls_get_value (tls_key_type key) 00089 { 00090 return pthread_getspecific (*key); 00091 } 00092 00093 00094 void 00095 tls_set_value (tls_key_type key, tls_value_type value) 00096 { 00097 pthread_setspecific(*key, value); 00098 } 00099 00100 00101 void 00102 tls_cleanup (tls_key_type key) 00103 { 00104 pthread_key_delete (*key); 00105 delete key; 00106 } 00107 00108 00109 #elif defined (LOG4CPLUS_USE_WIN32_THREADS) 00110 tls_key_type 00111 tls_init (tls_init_cleanup_func_type) 00112 { 00113 return TlsAlloc (); 00114 } 00115 00116 00117 tls_value_type tls_get_value (tls_key_type k) 00118 { 00119 return TlsGetValue (k); 00120 } 00121 00122 00123 void 00124 tls_set_value (tls_key_type k, tls_value_type value) 00125 { 00126 TlsSetValue (k, value); 00127 } 00128 00129 00130 void 00131 tls_cleanup (tls_key_type k) 00132 { 00133 TlsFree (k); 00134 } 00135 00136 00137 #elif defined (LOG4CPLUS_SINGLE_THREADED) 00138 extern std::vector<tls_value_type> * tls_single_threaded_values; 00139 00140 00141 tls_key_type 00142 tls_init (tls_init_cleanup_func_type) 00143 { 00144 if (! tls_single_threaded_values) 00145 tls_single_threaded_values = new std::vector<tls_value_type>; 00146 tls_key_type key = tls_single_threaded_values->size (); 00147 tls_single_threaded_values->resize (key + 1); 00148 return key; 00149 } 00150 00151 00152 tls_value_type 00153 tls_get_value (tls_key_type k) 00154 { 00155 assert (k < tls_single_threaded_values->size ()); 00156 return (*tls_single_threaded_values)[k]; 00157 } 00158 00159 00160 void 00161 tls_set_value (tls_key_type k, tls_value_type val) 00162 { 00163 assert (k < tls_single_threaded_values->size ()); 00164 (*tls_single_threaded_values)[k] = val; 00165 } 00166 00167 00168 void 00169 tls_cleanup (tls_key_type k) 00170 { 00171 assert (k < tls_single_threaded_values->size ()); 00172 (*tls_single_threaded_values)[k] = 0; 00173 } 00174 00175 #endif 00176 00177 00178 } } } // namespace log4cplus { namespace thread { namespace impl { 00179 00180 #endif // LOG4CPLUS_THREAD_IMPL_TLS_H