+#if wxUSE_THREADS
+/* static */
+wxLog *wxLog::SetThreadActiveTarget(wxLog *logger)
+{
+ wxASSERT_MSG( !wxThread::IsMain(), "use SetActiveTarget() for main thread" );
+
+ wxLog * const oldLogger = wxThreadInfo.logger;
+ if ( oldLogger )
+ oldLogger->Flush();
+
+ wxThreadInfo.logger = logger;
+
+ return oldLogger;
+}
+#endif // wxUSE_THREADS
+
+void wxLog::DontCreateOnDemand()
+{
+ ms_bAutoCreate = false;
+
+ // this is usually called at the end of the program and we assume that it
+ // is *always* called at the end - so we free memory here to avoid false
+ // memory leak reports from wxWin memory tracking code
+ ClearTraceMasks();
+}
+
+void wxLog::DoCreateOnDemand()
+{
+ ms_bAutoCreate = true;
+}
+
+// ----------------------------------------------------------------------------
+// wxLog components levels
+// ----------------------------------------------------------------------------
+
+/* static */
+void wxLog::SetComponentLevel(const wxString& component, wxLogLevel level)
+{
+ if ( component.empty() )
+ {
+ SetLogLevel(level);
+ }
+ else
+ {
+ wxCRIT_SECT_LOCKER(lock, GetLevelsCS());
+
+ GetComponentLevels()[component] = level;
+ }
+}
+
+/* static */
+wxLogLevel wxLog::GetComponentLevel(wxString component)
+{
+ wxCRIT_SECT_LOCKER(lock, GetLevelsCS());
+
+ const wxStringToNumHashMap& componentLevels = GetComponentLevels();
+ while ( !component.empty() )
+ {
+ wxStringToNumHashMap::const_iterator
+ it = componentLevels.find(component);
+ if ( it != componentLevels.end() )
+ return static_cast<wxLogLevel>(it->second);
+
+ component = component.BeforeLast('/');
+ }
+
+ return GetLogLevel();
+}
+
+// ----------------------------------------------------------------------------
+// wxLog trace masks
+// ----------------------------------------------------------------------------
+
+namespace
+{
+
+// because IsAllowedTraceMask() may be called during static initialization
+// (this is not recommended but it may still happen, see #11592) we can't use a
+// simple static variable which might be not initialized itself just yet to
+// store the trace masks, but need this accessor function which will ensure
+// that the variable is always correctly initialized before being accessed
+//
+// notice that this doesn't make accessing it MT-safe, of course, you need to
+// serialize accesses to it using GetTraceMaskCS() for this
+wxArrayString& TraceMasks()
+{
+ static wxArrayString s_traceMasks;
+
+ return s_traceMasks;
+}
+
+} // anonymous namespace
+
+/* static */ const wxArrayString& wxLog::GetTraceMasks()
+{
+ // because of this function signature (it returns a reference, not the
+ // object), it is inherently MT-unsafe so there is no need to acquire the
+ // lock here anyhow
+
+ return TraceMasks();
+}
+
+void wxLog::AddTraceMask(const wxString& str)
+{
+ wxCRIT_SECT_LOCKER(lock, GetTraceMaskCS());
+
+ TraceMasks().push_back(str);
+}
+