log4cplus  1.1.0
tls.h
Go to the documentation of this file.
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