#include <stdlib.h>
+#ifndef __WXPALMOS5__
#ifndef __WXWINCE__
#include <time.h>
#else
#include "wx/msw/wince/time.h"
#endif
+#endif /* ! __WXPALMOS5__ */
#if defined(__WINDOWS__)
#include "wx/msw/private.h" // includes windows.h
#endif
+#if wxUSE_THREADS
+
+// define static functions providing access to the critical sections we use
+// instead of just using static critical section variables as log functions may
+// be used during static initialization and while this is certainly not
+// advisable it's still better to not crash (as we'd do if we used a yet
+// uninitialized critical section) if it happens
+
+static inline wxCriticalSection& GetTraceMaskCS()
+{
+ static wxCriticalSection s_csTrace;
+
+ return s_csTrace;
+}
+
+static inline wxCriticalSection& GetPreviousLogCS()
+{
+ static wxCriticalSection s_csPrev;
+
+ return s_csPrev;
+}
+
+#endif // wxUSE_THREADS
+
// ----------------------------------------------------------------------------
// non member functions
// ----------------------------------------------------------------------------
// wxLog class implementation
// ----------------------------------------------------------------------------
-unsigned wxLog::LogLastRepetitionCountIfNeeded()
+unsigned wxLog::LogLastRepeatIfNeeded()
{
- wxCRIT_SECT_LOCKER(lock, ms_prevCS);
+ wxCRIT_SECT_LOCKER(lock, GetPreviousLogCS());
+
+ return LogLastRepeatIfNeededUnlocked();
+}
+unsigned wxLog::LogLastRepeatIfNeededUnlocked()
+{
const unsigned count = ms_prevCounter;
if ( ms_prevCounter )
wxLog::~wxLog()
{
- LogLastRepetitionCountIfNeeded();
+ // Flush() must be called before destroying the object as otherwise some
+ // messages could be lost
+ if ( ms_prevCounter )
+ {
+ wxMessageOutputDebug().Printf
+ (
+ wxS("Last repeated message (\"%s\", %lu times) wasn't output"),
+ ms_prevString,
+ ms_prevCounter
+ );
+ }
}
/* static */
{
if ( GetRepetitionCounting() )
{
- wxCRIT_SECT_LOCKER(lock, ms_prevCS);
+ wxCRIT_SECT_LOCKER(lock, GetPreviousLogCS());
if ( szString == ms_prevString )
{
return;
}
- pLogger->LogLastRepetitionCountIfNeeded();
+ pLogger->LogLastRepeatIfNeededUnlocked();
// reset repetition counter for a new message
ms_prevString = szString;
ms_bAutoCreate = true;
}
+void wxLog::AddTraceMask(const wxString& str)
+{
+ wxCRIT_SECT_LOCKER(lock, GetTraceMaskCS());
+
+ ms_aTraceMasks.push_back(str);
+}
+
void wxLog::RemoveTraceMask(const wxString& str)
{
+ wxCRIT_SECT_LOCKER(lock, GetTraceMaskCS());
+
int index = ms_aTraceMasks.Index(str);
if ( index != wxNOT_FOUND )
ms_aTraceMasks.RemoveAt((size_t)index);
void wxLog::ClearTraceMasks()
{
+ wxCRIT_SECT_LOCKER(lock, GetTraceMaskCS());
+
ms_aTraceMasks.Clear();
}
void wxLog::Flush()
{
- // nothing to do here
+ LogLastRepeatIfNeeded();
}
/*static*/ bool wxLog::IsAllowedTraceMask(const wxString& mask)
{
+ wxCRIT_SECT_LOCKER(lock, GetTraceMaskCS());
+
for ( wxArrayString::iterator it = ms_aTraceMasks.begin(),
en = ms_aTraceMasks.end();
it != en; ++it )
+ {
if ( *it == mask)
return true;
+ }
+
return false;
}
wxLogInterposerTemp::wxLogInterposerTemp()
: wxLogChain(this)
{
- DetachOldLog();
+ DetachOldLog();
}
#ifdef __VISUALC__
// static variables
// ----------------------------------------------------------------------------
-#if wxUSE_THREADS
-wxCriticalSection wxLog::ms_prevCS;
-#endif // wxUSE_THREADS
bool wxLog::ms_bRepetCounting = false;
wxString wxLog::ms_prevString;
unsigned int wxLog::ms_prevCounter = 0;