1. wxLog::FlushActive() added
2. threads can be used in console mode git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3877 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -132,6 +132,13 @@ public:
|
|||||||
bool HasPendingMessages() const { return m_bHasMessages; }
|
bool HasPendingMessages() const { return m_bHasMessages; }
|
||||||
|
|
||||||
// only one sink is active at each moment
|
// only one sink is active at each moment
|
||||||
|
// flush the active target if any
|
||||||
|
static void FlushActive()
|
||||||
|
{
|
||||||
|
wxLog *log = GetActiveTarget();
|
||||||
|
if ( log )
|
||||||
|
log->Flush();
|
||||||
|
}
|
||||||
// get current log target, will call wxApp::CreateLogTarget() to
|
// get current log target, will call wxApp::CreateLogTarget() to
|
||||||
// create one if none exists
|
// create one if none exists
|
||||||
static wxLog *GetActiveTarget();
|
static wxLog *GetActiveTarget();
|
||||||
|
@@ -12,18 +12,95 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
|
#include <wx/file.h>
|
||||||
#include <wx/app.h>
|
#include <wx/app.h>
|
||||||
|
#include <wx/thread.h>
|
||||||
|
|
||||||
int main()
|
static size_t gs_counter = (size_t)-1;
|
||||||
|
static wxCriticalSection gs_critsect;
|
||||||
|
|
||||||
|
class MyThread : public wxThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyThread(char ch);
|
||||||
|
|
||||||
|
// thread execution starts here
|
||||||
|
virtual void *Entry();
|
||||||
|
|
||||||
|
// and stops here
|
||||||
|
virtual void OnExit();
|
||||||
|
|
||||||
|
public:
|
||||||
|
char m_ch;
|
||||||
|
};
|
||||||
|
|
||||||
|
MyThread::MyThread(char ch)
|
||||||
|
{
|
||||||
|
m_ch = ch;
|
||||||
|
|
||||||
|
Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MyThread::Entry()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
wxCriticalSectionLocker lock(gs_critsect);
|
||||||
|
if ( gs_counter == (size_t)-1 )
|
||||||
|
gs_counter = 1;
|
||||||
|
else
|
||||||
|
gs_counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t n = 0; n < 10; n++ )
|
||||||
|
{
|
||||||
|
if ( TestDestroy() )
|
||||||
|
break;
|
||||||
|
|
||||||
|
putchar(m_ch);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
wxThread::Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyThread::OnExit()
|
||||||
|
{
|
||||||
|
wxCriticalSectionLocker lock(gs_critsect);
|
||||||
|
gs_counter--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if ( !wxInitialize() )
|
if ( !wxInitialize() )
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
|
fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString s("Hello, ");
|
static const size_t nThreads = 3;
|
||||||
|
MyThread *threads[nThreads];
|
||||||
|
size_t n;
|
||||||
|
for ( n = 0; n < nThreads; n++ )
|
||||||
|
{
|
||||||
|
threads[n] = new MyThread('+' + n);
|
||||||
|
threads[n]->Run();
|
||||||
|
}
|
||||||
|
|
||||||
wxLogMessage(s + "world!");
|
// wait until all threads terminate
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
wxCriticalSectionLocker lock(gs_critsect);
|
||||||
|
if ( !gs_counter )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("\nThat's all, folks!");
|
||||||
|
|
||||||
|
for ( n = 0; n < nThreads; n++ )
|
||||||
|
{
|
||||||
|
threads[n]->Delete();
|
||||||
|
}
|
||||||
|
|
||||||
wxUninitialize();
|
wxUninitialize();
|
||||||
|
|
||||||
|
@@ -33,6 +33,12 @@ wxApp * WXDLLEXPORT wxTheApp = NULL;
|
|||||||
wxAppInitializerFunction
|
wxAppInitializerFunction
|
||||||
wxAppBase::m_appInitFn = (wxAppInitializerFunction)NULL;
|
wxAppBase::m_appInitFn = (wxAppInitializerFunction)NULL;
|
||||||
|
|
||||||
|
#if wxUSE_THREADS
|
||||||
|
// List of events pending processing
|
||||||
|
wxList *wxPendingEvents = NULL;
|
||||||
|
wxCriticalSection *wxPendingEventsLocker = NULL;
|
||||||
|
#endif // wxUSE_THREADS
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// private classes
|
// private classes
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -55,7 +61,7 @@ static size_t gs_nInitCount = 0;
|
|||||||
|
|
||||||
bool WXDLLEXPORT wxInitialize()
|
bool WXDLLEXPORT wxInitialize()
|
||||||
{
|
{
|
||||||
if ( gs_nInitCount++ )
|
if ( gs_nInitCount )
|
||||||
{
|
{
|
||||||
// already initialized
|
// already initialized
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -64,15 +70,34 @@ bool WXDLLEXPORT wxInitialize()
|
|||||||
wxASSERT_MSG( !wxTheApp,
|
wxASSERT_MSG( !wxTheApp,
|
||||||
T("either call wxInitialize or create app, not both!") );
|
T("either call wxInitialize or create app, not both!") );
|
||||||
|
|
||||||
|
wxClassInfo::InitializeClasses();
|
||||||
|
|
||||||
|
wxModule::RegisterModules();
|
||||||
|
if ( !wxModule::InitializeModules() )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
wxTheApp = new wxConsoleApp;
|
wxTheApp = new wxConsoleApp;
|
||||||
|
|
||||||
return wxTheApp != NULL;
|
if ( !wxTheApp )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gs_nInitCount++;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WXDLLEXPORT wxUninitialize()
|
void WXDLLEXPORT wxUninitialize()
|
||||||
{
|
{
|
||||||
if ( !--gs_nInitCount )
|
if ( !--gs_nInitCount )
|
||||||
{
|
{
|
||||||
|
wxModule::CleanUpModules();
|
||||||
|
|
||||||
|
wxClassInfo::CleanUpClasses();
|
||||||
|
|
||||||
// delete the application object
|
// delete the application object
|
||||||
delete wxTheApp;
|
delete wxTheApp;
|
||||||
wxTheApp = (wxApp *)NULL;
|
wxTheApp = (wxApp *)NULL;
|
||||||
|
@@ -351,6 +351,8 @@ wxThreadInternal::wxThreadInternal()
|
|||||||
{
|
{
|
||||||
m_state = STATE_NEW;
|
m_state = STATE_NEW;
|
||||||
m_cancelled = FALSE;
|
m_cancelled = FALSE;
|
||||||
|
m_prio = WXTHREAD_DEFAULT_PRIORITY;
|
||||||
|
m_threadId = 0;
|
||||||
|
|
||||||
// this mutex is locked during almost all thread lifetime - it will only be
|
// this mutex is locked during almost all thread lifetime - it will only be
|
||||||
// unlocked in the very end
|
// unlocked in the very end
|
||||||
@@ -536,6 +538,17 @@ wxThreadError wxThread::Create()
|
|||||||
wxLogError(_("Cannot get priority range for scheduling policy %d."),
|
wxLogError(_("Cannot get priority range for scheduling policy %d."),
|
||||||
prio);
|
prio);
|
||||||
}
|
}
|
||||||
|
else if ( max_prio == min_prio )
|
||||||
|
{
|
||||||
|
if ( p_internal->GetPriority() != WXTHREAD_DEFAULT_PRIORITY )
|
||||||
|
{
|
||||||
|
// notify the programmer that this doesn't work here
|
||||||
|
wxLogWarning(_("Thread priority setting is ignored."));
|
||||||
|
}
|
||||||
|
//else: we have default priority, so don't complain
|
||||||
|
|
||||||
|
// anyhow, don't do anything because priority is just ignored
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct sched_param sp;
|
struct sched_param sp;
|
||||||
@@ -567,6 +580,9 @@ wxThreadError wxThread::Create()
|
|||||||
|
|
||||||
wxThreadError wxThread::Run()
|
wxThreadError wxThread::Run()
|
||||||
{
|
{
|
||||||
|
wxCHECK_MSG( p_internal->GetId(), wxTHREAD_MISC_ERROR,
|
||||||
|
T("must call wxThread::Create() first") );
|
||||||
|
|
||||||
return p_internal->Run();
|
return p_internal->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,11 +785,15 @@ wxThread::~wxThread()
|
|||||||
m_critsect.Enter();
|
m_critsect.Enter();
|
||||||
if ( p_internal->GetState() != STATE_EXITED &&
|
if ( p_internal->GetState() != STATE_EXITED &&
|
||||||
p_internal->GetState() != STATE_NEW )
|
p_internal->GetState() != STATE_NEW )
|
||||||
wxLogDebug(T("The thread is being destroyed althought it is still running ! The application may crash."));
|
{
|
||||||
|
wxLogDebug(T("The thread is being destroyed although it is still "
|
||||||
|
"running! The application may crash."));
|
||||||
|
}
|
||||||
|
|
||||||
m_critsect.Leave();
|
m_critsect.Leave();
|
||||||
|
|
||||||
delete p_internal;
|
delete p_internal;
|
||||||
|
|
||||||
// remove this thread from the global array
|
// remove this thread from the global array
|
||||||
gs_allThreads.Remove(this);
|
gs_allThreads.Remove(this);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user