From 2e7f384517ccb08cec87dd233c8f11f876b65e5c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 31 Aug 2006 11:31:02 +0000 Subject: [PATCH] don't use static buffer needing a critical section to protect it for logging; this results in deadlocks if the log sink decides to log itself (and this can be very difficult to prevent) and is unnecessary anyhow as the initial goal of allowing wxLog to work even for out of memory errors has never been tested and presumably never worked git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40935 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/log.h | 18 +++-- src/common/log.cpp | 163 ++++++++++----------------------------------- 2 files changed, 45 insertions(+), 136 deletions(-) diff --git a/include/wx/log.h b/include/wx/log.h index 71be9b337b..0e548d2bbe 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -121,13 +121,6 @@ public: // ctor wxLog(){} - // Internal buffer. - - // Allow replacement of the fixed size static buffer with - // a user allocated one. Pass in NULL to restore the - // built in static buffer. - static wxChar *SetLogBuffer( wxChar *buf, size_t size = 0 ); - // these functions allow to completely disable all log messages // is logging disabled now? @@ -135,7 +128,7 @@ public: // change the flag state, return the previous one static bool EnableLogging(bool doIt = true) - { bool doLogOld = ms_doLog; ms_doLog = doIt; return doLogOld; } + { bool doLogOld = ms_doLog; ms_doLog = doIt; return doLogOld; } // static sink function - see DoLog() for function to overload in the // derived classes @@ -190,7 +183,7 @@ public: // log the count of repeating messages instead of logging the messages // multiple times static void SetRepetitionCounting(bool bRepetCounting = true) - { ms_bRepetCounting = bRepetCounting; } + { ms_bRepetCounting = bRepetCounting; } // gets duplicate counting status static bool GetRepetitionCounting() { return ms_bRepetCounting; } @@ -200,7 +193,7 @@ public: // add string trace mask static void AddTraceMask(const wxString& str) - { ms_aTraceMasks.push_back(str); } + { ms_aTraceMasks.push_back(str); } // add string trace mask static void RemoveTraceMask(const wxString& str); @@ -248,6 +241,11 @@ public: // this method exists for backwards compatibility only, don't use bool HasPendingMessages() const { return true; } +#if WXWIN_COMPATIBILITY_2_6 + // this function doesn't do anything any more, don't call it + wxDEPRECATED( static wxChar *SetLogBuffer(wxChar *buf, size_t size = 0) ); +#endif + protected: // the logging functions that can be overriden diff --git a/src/common/log.cpp b/src/common/log.cpp index 275ed6dcd9..affdec61cb 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -75,27 +75,6 @@ // implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// globals -// ---------------------------------------------------------------------------- - -// log functions can't allocate memory (LogError("out of memory...") should -// work!), so we use a static buffer for all log messages -#define LOG_BUFFER_SIZE (4096) - -// static buffer for error messages -static wxChar s_szBufStatic[LOG_BUFFER_SIZE]; - -static wxChar *s_szBuf = s_szBufStatic; -static size_t s_szBufSize = WXSIZEOF( s_szBufStatic ); - -#if wxUSE_THREADS - -// the critical section protecting the static buffer -static wxCriticalSection gs_csLogBuf; - -#endif // wxUSE_THREADS - // ---------------------------------------------------------------------------- // implementation of Log functions // @@ -103,26 +82,11 @@ static wxCriticalSection gs_csLogBuf; // macros and not all compilers inline vararg functions. // ---------------------------------------------------------------------------- -// wrapper for wxVsnprintf(s_szBuf) which always NULL-terminates it -static inline void PrintfInLogBuf(const wxChar *szFormat, va_list argptr) -{ - if ( wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr) < 0 ) - { - // must NUL-terminate it manually - s_szBuf[s_szBufSize - 1] = _T('\0'); - } - //else: NUL-terminated by vsnprintf() -} - // generic log function void wxVLogGeneric(wxLogLevel level, const wxChar *szFormat, va_list argptr) { if ( wxLog::IsEnabled() ) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - - PrintfInLogBuf(szFormat, argptr); - - wxLog::OnLog(level, s_szBuf, time(NULL)); + wxLog::OnLog(level, wxString::FormatV(szFormat, argptr), time(NULL)); } } @@ -138,11 +102,8 @@ void wxLogGeneric(wxLogLevel level, const wxChar *szFormat, ...) void wxVLog##level(const wxChar *szFormat, va_list argptr) \ { \ if ( wxLog::IsEnabled() ) { \ - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \ - \ - PrintfInLogBuf(szFormat, argptr); \ - \ - wxLog::OnLog(wxLOG_##level, s_szBuf, time(NULL)); \ + wxLog::OnLog(wxLOG_##level, \ + wxString::FormatV(szFormat, argptr), time(NULL));\ } \ } \ \ @@ -174,9 +135,7 @@ void wxSafeShowMessage(const wxString& title, const wxString& text) // always terminate the program void wxVLogFatalError(const wxChar *szFormat, va_list argptr) { - wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); - - wxSafeShowMessage(_T("Fatal Error"), s_szBuf); + wxSafeShowMessage(_T("Fatal Error"), wxString::FormatV(szFormat, argptr)); #ifdef __WXWINCE__ ExitThread(3); @@ -201,11 +160,8 @@ void wxVLogVerbose(const wxChar *szFormat, va_list argptr) { if ( wxLog::IsEnabled() ) { if ( wxLog::GetActiveTarget() != NULL && wxLog::GetVerbose() ) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - - wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); - - wxLog::OnLog(wxLOG_Info, s_szBuf, time(NULL)); + wxLog::OnLog(wxLOG_Info, + wxString::FormatV(szFormat, argptr), time(NULL)); } } } @@ -224,13 +180,11 @@ void wxLogVerbose(const wxChar *szFormat, ...) void wxVLog##level(const wxChar *szFormat, va_list argptr) \ { \ if ( wxLog::IsEnabled() ) { \ - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \ - \ - wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); \ - \ - wxLog::OnLog(wxLOG_##level, s_szBuf, time(NULL)); \ + wxLog::OnLog(wxLOG_##level, \ + wxString::FormatV(szFormat, argptr), time(NULL));\ } \ } \ + \ void wxLog##level(const wxChar *szFormat, ...) \ { \ va_list argptr; \ @@ -242,25 +196,10 @@ void wxLogVerbose(const wxChar *szFormat, ...) void wxVLogTrace(const wxChar *mask, const wxChar *szFormat, va_list argptr) { if ( wxLog::IsEnabled() && wxLog::IsAllowedTraceMask(mask) ) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - - wxChar *p = s_szBuf; - size_t len = s_szBufSize; - wxStrncpy(s_szBuf, _T("("), len); - len -= 1; // strlen("(") - p += 1; - wxStrncat(p, mask, len); - size_t lenMask = wxStrlen(mask); - len -= lenMask; - p += lenMask; - - wxStrncat(p, _T(") "), len); - len -= 2; - p += 2; - - wxVsnprintf(p, len, szFormat, argptr); - - wxLog::OnLog(wxLOG_Trace, s_szBuf, time(NULL)); + wxString msg; + msg << _T("(") << mask << _T(") ") << wxString::FormatV(szFormat, argptr); + + wxLog::OnLog(wxLOG_Trace, msg, time(NULL)); } } @@ -278,11 +217,7 @@ void wxLogVerbose(const wxChar *szFormat, ...) // that wxLogTrace(wxTraceRefCount | wxTraceOle) will only do something // if both bits are set. if ( wxLog::IsEnabled() && ((wxLog::GetTraceMask() & mask) == mask) ) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - - wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); - - wxLog::OnLog(wxLOG_Trace, s_szBuf, time(NULL)); + wxLog::OnLog(wxLOG_Trace, wxString::FormatV(szFormat, argptr), time(NULL)); } } @@ -304,26 +239,15 @@ IMPLEMENT_LOG_DEBUG_FUNCTION(Trace) // wxLogSysError: one uses the last error code, for other you must give it // explicitly -// common part of both wxLogSysError -void wxLogSysErrorHelper(long lErrCode) +// return the system error message description +static inline wxString wxLogSysErrorHelper(long err) { - wxChar szErrMsg[LOG_BUFFER_SIZE / 2]; - wxSnprintf(szErrMsg, WXSIZEOF(szErrMsg), - _(" (error %ld: %s)"), lErrCode, wxSysErrorMsg(lErrCode)); - wxStrncat(s_szBuf, szErrMsg, s_szBufSize - wxStrlen(s_szBuf)); - - wxLog::OnLog(wxLOG_Error, s_szBuf, time(NULL)); + return wxString::Format(_(" (error %ld: %s)"), err, wxSysErrorMsg(err)); } void WXDLLEXPORT wxVLogSysError(const wxChar *szFormat, va_list argptr) { - if ( wxLog::IsEnabled() ) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - - wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); - - wxLogSysErrorHelper(wxSysErrorCode()); - } + wxVLogSysError(wxSysErrorCode(), szFormat, argptr); } void WXDLLEXPORT wxLogSysError(const wxChar *szFormat, ...) @@ -334,14 +258,12 @@ void WXDLLEXPORT wxLogSysError(const wxChar *szFormat, ...) va_end(argptr); } -void WXDLLEXPORT wxVLogSysError(long lErrCode, const wxChar *szFormat, va_list argptr) +void WXDLLEXPORT wxVLogSysError(long err, const wxChar *fmt, va_list argptr) { if ( wxLog::IsEnabled() ) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - - wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); - - wxLogSysErrorHelper(lErrCode); + wxLog::OnLog(wxLOG_Error, + wxString::FormatV(fmt, argptr) + wxLogSysErrorHelper(err), + time(NULL)); } } @@ -417,22 +339,10 @@ void wxLog::OnLog(wxLogLevel level, const wxChar *szString, time_t t) } } -wxChar *wxLog::SetLogBuffer( wxChar *buf, size_t size) +// deprecated function +wxChar *wxLog::SetLogBuffer(wxChar * WXUNUSED(buf), size_t WXUNUSED(size)) { - wxChar *oldbuf = s_szBuf; - - if( buf == 0 ) - { - s_szBuf = s_szBufStatic; - s_szBufSize = WXSIZEOF( s_szBufStatic ); - } - else - { - s_szBuf = buf; - s_szBufSize = size; - } - - return (oldbuf == s_szBufStatic ) ? 0 : oldbuf; + return NULL; } wxLog *wxLog::GetActiveTarget() @@ -834,7 +744,7 @@ const wxChar *wxSysErrorMsg(unsigned long nErrCode) nErrCode = wxSysErrorCode(); #if defined(__WXMSW__) && !defined(__WXMICROWIN__) - static wxChar s_szBuf[LOG_BUFFER_SIZE / 2]; + static wxChar s_szBuf[1024]; // get error message from system LPVOID lpMsgBuf; @@ -876,21 +786,22 @@ const wxChar *wxSysErrorMsg(unsigned long nErrCode) } } else -#endif +#endif // !__SMARTPHONE__ { s_szBuf[0] = wxT('\0'); } return s_szBuf; -#else // Unix-WXMICROWIN -#if wxUSE_UNICODE - static wxChar s_szBuf[LOG_BUFFER_SIZE / 2]; - wxConvCurrent->MB2WC(s_szBuf, strerror(nErrCode), WXSIZEOF(s_szBuf) -1); - return s_szBuf; -#else - return strerror((int)nErrCode); -#endif -#endif // Win/Unix-WXMICROWIN +#else // !__WXMSW__ + #if wxUSE_UNICODE + static wchar_t s_wzBuf[1024]; + wxConvCurrent->MB2WC(s_wzBuf, strerror((int)nErrCode), + WXSIZEOF(s_wzBuf) - 1); + return s_wzBuf; + #else + return strerror((int)nErrCode); + #endif +#endif // __WXMSW__/!__WXMSW__ } #endif // wxUSE_LOG -- 2.45.2