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
This commit is contained in:
Vadim Zeitlin
2006-08-31 11:31:02 +00:00
parent 6a93571daf
commit 2e7f384517
2 changed files with 45 additions and 136 deletions

View File

@@ -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

View File

@@ -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