log4cplus  1.1.0
internal.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // Module:  Log4CPLUS
00003 // File:    internal.h
00004 // Created: 1/2009
00005 // Author:  Vaclav Haisman
00006 //
00007 //
00008 //  Copyright (C) 2009-2010, Vaclav Haisman. All rights reserved.
00009 //  
00010 //  Redistribution and use in source and binary forms, with or without modifica-
00011 //  tion, are permitted provided that the following conditions are met:
00012 //  
00013 //  1. Redistributions of  source code must  retain the above copyright  notice,
00014 //     this list of conditions and the following disclaimer.
00015 //  
00016 //  2. Redistributions in binary form must reproduce the above copyright notice,
00017 //     this list of conditions and the following disclaimer in the documentation
00018 //     and/or other materials provided with the distribution.
00019 //  
00020 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
00021 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00022 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
00023 //  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
00024 //  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
00025 //  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
00026 //  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
00027 //  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
00028 //  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
00029 //  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 
00037 #ifndef LOG4CPLUS_INTERNAL_INTERNAL_HEADER_
00038 #define LOG4CPLUS_INTERNAL_INTERNAL_HEADER_
00039 
00040 #include <log4cplus/config.hxx>
00041 
00042 #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
00043 #pragma once
00044 #endif
00045 
00046 #if ! defined (INSIDE_LOG4CPLUS)
00047 #  error "This header must not be be used outside log4cplus' implementation files."
00048 #endif
00049 
00050 #include <memory>
00051 #include <vector>
00052 #include <sstream>
00053 #include <cstdio>
00054 #include <log4cplus/tstring.h>
00055 #include <log4cplus/streams.h>
00056 #include <log4cplus/ndc.h>
00057 #include <log4cplus/mdc.h>
00058 #include <log4cplus/spi/loggingevent.h>
00059 #include <log4cplus/thread/impl/tls.h>
00060 #include <log4cplus/helpers/snprintf.h>
00061 
00062 
00063 namespace log4cplus {
00064 
00065 namespace internal {
00066 
00067 
00070 extern log4cplus::tstring const empty_str;
00071 
00072 
00073 struct gft_scratch_pad
00074 {
00075     gft_scratch_pad ();
00076     ~gft_scratch_pad ();
00077     
00078     void
00079     reset ()
00080     {
00081         uc_q_str_valid = false;
00082         q_str_valid = false;
00083         s_str_valid = false;
00084         ret.clear ();
00085     }
00086     
00087     log4cplus::tstring q_str;
00088     log4cplus::tstring uc_q_str;
00089     log4cplus::tstring s_str;
00090     log4cplus::tstring ret;
00091     log4cplus::tstring fmt;
00092     log4cplus::tstring tmp;
00093     std::vector<tchar> buffer;
00094     bool uc_q_str_valid;
00095     bool q_str_valid;
00096     bool s_str_valid;
00097 };
00098 
00099 
00100 struct appender_sratch_pad
00101 {
00102     appender_sratch_pad ();
00103     ~appender_sratch_pad ();
00104 
00105     tostringstream oss;
00106     tstring str;
00107     std::string chstr;
00108 };
00109 
00110 
00112 struct per_thread_data
00113 {
00114     per_thread_data ();
00115     ~per_thread_data ();
00116 
00117     tostringstream macros_oss;
00118     tostringstream layout_oss;
00119     DiagnosticContextStack ndc_dcs;
00120     MappedDiagnosticContextMap mdc_map;
00121     log4cplus::tstring thread_name;
00122     log4cplus::tstring thread_name2;
00123     gft_scratch_pad gft_sp;
00124     appender_sratch_pad appender_sp;
00125     log4cplus::tstring faa_str;
00126     log4cplus::tstring ll_str;
00127     spi::InternalLoggingEvent forced_log_ev;
00128     std::FILE * fnull;
00129     log4cplus::helpers::snprintf_buf snprintf_buf;
00130 };
00131 
00132 
00133 per_thread_data * alloc_ptd ();
00134 
00135 // TLS key whose value is pointer struct per_thread_data.
00136 extern log4cplus::thread::impl::tls_key_type tls_storage_key;
00137 
00138 
00139 #if ! defined (LOG4CPLUS_SINGLE_THREADED) \
00140     && defined (LOG4CPLUS_THREAD_LOCAL_VAR)
00141 
00142 extern LOG4CPLUS_THREAD_LOCAL_VAR per_thread_data * ptd;
00143 
00144 
00145 inline
00146 void
00147 set_ptd (per_thread_data * p)
00148 {
00149     ptd = p;
00150 }
00151 
00152 
00155 inline
00156 per_thread_data *
00157 get_ptd (bool alloc
00158 #if defined (_WIN32) && defined (LOG4CPLUS_BUILD_DLL)
00159          = false
00160 #else
00161          = true
00162 #endif
00163          )
00164 {
00165     if (LOG4CPLUS_UNLIKELY (! ptd && alloc))
00166         return alloc_ptd ();
00167 
00168     // The assert() does not belong here. get_ptd() might be called by
00169     // cleanup code that can handle the returned NULL pointer.
00170     //assert (ptd);
00171 
00172     return ptd;
00173 }
00174 
00175 
00176 #else // defined (LOG4CPLUS_THREAD_LOCAL_VAR)
00177 
00178 
00179 inline
00180 void
00181 set_ptd (per_thread_data * p)
00182 {
00183     thread::impl::tls_set_value (tls_storage_key, p);
00184 }
00185 
00186 
00187 inline
00188 per_thread_data *
00189 get_ptd (bool alloc = true)
00190 {
00191     per_thread_data * ptd
00192         = reinterpret_cast<per_thread_data *>(
00193             thread::impl::tls_get_value (tls_storage_key));
00194 
00195     if (LOG4CPLUS_UNLIKELY (! ptd && alloc))
00196         return alloc_ptd ();
00197 
00198     return ptd;
00199 }
00200 
00201 
00202 #endif // defined (LOG4CPLUS_THREAD_LOCAL_VAR)
00203 
00204 
00205 inline
00206 tstring &
00207 get_thread_name_str ()
00208 {
00209     return get_ptd ()->thread_name;
00210 }
00211 
00212 
00213 inline
00214 tstring &
00215 get_thread_name2_str ()
00216 {
00217     return get_ptd ()->thread_name2;
00218 }
00219 
00220 
00221 inline
00222 gft_scratch_pad &
00223 get_gft_scratch_pad ()
00224 {
00225     return get_ptd ()->gft_sp;
00226 }
00227 
00228 
00229 inline
00230 appender_sratch_pad &
00231 get_appender_sp ()
00232 {
00233     return get_ptd ()->appender_sp;
00234 }
00235 
00236 
00237 } // namespace internal {
00238 
00239 
00240 namespace detail
00241 {
00242 
00243 LOG4CPLUS_EXPORT void clear_tostringstream (tostringstream &);
00244 
00245 } // namespace detail
00246 
00247 
00248 } // namespace log4cplus { 
00249 
00250 
00251 #endif // LOG4CPLUS_INTERNAL_INTERNAL_HEADER_