Opened 2 years ago

Closed 23 months ago

#14595 closed defect (fixed)

Console application: Log messages from worker threads aren't displayed

Reported by: roed_bis Owned by:
Priority: low Milestone:
Component: base Version: 2.9.4
Keywords: console wxLog mt Cc:
Blocked By: Blocking:
Patch: no

Description

In GUI applications log messages from from worker threads are queued and displayed at idle time but in console application there's no message loop so queue will never be flushed.

Maybe this is not a bug but at minimum documentation needs clarification.
A simple workaround is to create separate log object in a worker thread:

wxLogStderr log;
wxLog::SetThreadActiveTarget( &log );

I don't know is there an elegant way to distinguish between console and GUI application at runtime. Maybe application traits? HasStderr or CanUseStderr function?

Change History (5)

comment:1 follow-up: Changed 2 years ago by vadz

  • Keywords wxLog mt added
  • Priority changed from lowest to low
  • Status changed from new to confirmed

We should flush all threads logs on application exit. It's probably not ideal but just losing them is even worse...

Could you please check whether adding wxLog::FlushActive() to wxAppConsoleBase::OnExit() does this?

comment:2 in reply to: ↑ 1 Changed 2 years ago by roed_bis

Checked. wxLog::FlushActive works in OnExit but this is far from good solution.

comment:3 follow-up: Changed 2 years ago by vadz

I wanted to add this but realized that we already had a call to wxLog::SetActiveTarget(NULL) which is supposed to take care of this in wxEntryCleanup(), called from wxUninitialize(). Do you call this function from your code? If so, I'd really like to have a small sample reproducing the problem.

As for a better solution, the only one I see is to add wxLog::IsMTSafe() method which would return false by default but could return true for e.g. wxLogStderr (assuming we can be sure it's really MT-safe on all platforms!). Then we could use the logger directly from background threads if this method returned true. But in practice, it's not that different from simply setting this logger as per-thread logger.

comment:4 in reply to: ↑ 3 Changed 2 years ago by roed_bis

wxLog::SetActiveTarget(NULL) is called from wxUninitialize() but this function doesn't display queued logs. It only call Flush on active log target. And:

void wxLog::Flush()
{
    LogLastRepeatIfNeeded();
}

Queued logs are displayed at wxLog::FlushThreadMessages method. This method is called only from wxLog::FlushActive. wxLog::SetActiveTarget(NULL) do not call wxLog::FlushThreadMessages nor wxLog::FlushActive.

comment:5 Changed 23 months ago by VZ

  • Resolution set to fixed
  • Status changed from confirmed to closed

(In [72629]) Flush log messages from other threads on shutdown too.

Add a call to wxLog::FlushActive() to the shutdown code as calling just
wxLog::SetActiveTarget(NULL) is not enough, it flushes the current log target
only but not the ones used by other threads.

Closes #14595.

Note: See TracTickets for help on using tickets.