fixed the async process IO polling code
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16659 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -34,6 +34,9 @@
|
|||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/app.h"
|
#include "wx/app.h"
|
||||||
#include "wx/frame.h"
|
#include "wx/frame.h"
|
||||||
|
#include "wx/panel.h"
|
||||||
|
|
||||||
|
#include "wx/timer.h"
|
||||||
|
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
#include "wx/menu.h"
|
#include "wx/menu.h"
|
||||||
@@ -108,6 +111,7 @@ public:
|
|||||||
void OnAbout(wxCommandEvent& event);
|
void OnAbout(wxCommandEvent& event);
|
||||||
|
|
||||||
// polling output of async processes
|
// polling output of async processes
|
||||||
|
void OnTimer(wxTimerEvent& event);
|
||||||
void OnIdle(wxIdleEvent& event);
|
void OnIdle(wxIdleEvent& event);
|
||||||
|
|
||||||
// for MyPipedProcess
|
// for MyPipedProcess
|
||||||
@@ -121,6 +125,31 @@ private:
|
|||||||
|
|
||||||
void DoAsyncExec(const wxString& cmd);
|
void DoAsyncExec(const wxString& cmd);
|
||||||
|
|
||||||
|
void AddAsyncProcess(MyPipedProcess *process)
|
||||||
|
{
|
||||||
|
if ( m_running.IsEmpty() )
|
||||||
|
{
|
||||||
|
// we want to start getting the timer events to ensure that a
|
||||||
|
// steady stream of idle events comes in -- otherwise we
|
||||||
|
// wouldn't be able to poll the child process input
|
||||||
|
m_timerIdleWakeUp.Start(100);
|
||||||
|
}
|
||||||
|
//else: the timer is already running
|
||||||
|
|
||||||
|
m_running.Add(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveAsyncProcess(MyPipedProcess *process)
|
||||||
|
{
|
||||||
|
m_running.Remove(process);
|
||||||
|
|
||||||
|
if ( m_running.IsEmpty() )
|
||||||
|
{
|
||||||
|
// we don't need to get idle events all the time any more
|
||||||
|
m_timerIdleWakeUp.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the PID of the last process we launched asynchronously
|
// the PID of the last process we launched asynchronously
|
||||||
long m_pidLast;
|
long m_pidLast;
|
||||||
|
|
||||||
@@ -143,6 +172,9 @@ private:
|
|||||||
|
|
||||||
MyProcessesArray m_running;
|
MyProcessesArray m_running;
|
||||||
|
|
||||||
|
// the idle event wake up timer
|
||||||
|
wxTimer m_timerIdleWakeUp;
|
||||||
|
|
||||||
// any class wishing to process wxWindows events must use this macro
|
// any class wishing to process wxWindows events must use this macro
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
@@ -303,6 +335,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|||||||
EVT_MENU(Exec_About, MyFrame::OnAbout)
|
EVT_MENU(Exec_About, MyFrame::OnAbout)
|
||||||
|
|
||||||
EVT_IDLE(MyFrame::OnIdle)
|
EVT_IDLE(MyFrame::OnIdle)
|
||||||
|
|
||||||
|
EVT_TIMER(-1, MyFrame::OnTimer)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(MyPipeFrame, wxFrame)
|
BEGIN_EVENT_TABLE(MyPipeFrame, wxFrame)
|
||||||
@@ -354,7 +388,8 @@ bool MyApp::OnInit()
|
|||||||
|
|
||||||
// frame constructor
|
// frame constructor
|
||||||
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
||||||
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
|
: wxFrame((wxFrame *)NULL, -1, title, pos, size),
|
||||||
|
m_timerIdleWakeUp(this)
|
||||||
{
|
{
|
||||||
m_pidLast = 0;
|
m_pidLast = 0;
|
||||||
|
|
||||||
@@ -441,7 +476,7 @@ void MyFrame::OnClear(wxCommandEvent& WXUNUSED(event))
|
|||||||
|
|
||||||
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
wxMessageBox(_T("Exec wxWindows Sample\n<EFBFBD> 2000-2001 Vadim Zeitlin"),
|
wxMessageBox(_T("Exec wxWindows Sample\n<EFBFBD> 2000-2002 Vadim Zeitlin"),
|
||||||
_T("About Exec"), wxOK | wxICON_INFORMATION, this);
|
_T("About Exec"), wxOK | wxICON_INFORMATION, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,7 +698,7 @@ void MyFrame::OnExecWithRedirect(wxCommandEvent& WXUNUSED(event))
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_running.Add(process);
|
AddAsyncProcess(process);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,7 +729,7 @@ void MyFrame::OnExecWithPipe(wxCommandEvent& WXUNUSED(event))
|
|||||||
{
|
{
|
||||||
wxLogStatus( _T("Process %ld (%s) launched."), pid, cmd.c_str() );
|
wxLogStatus( _T("Process %ld (%s) launched."), pid, cmd.c_str() );
|
||||||
|
|
||||||
m_running.Add(process);
|
AddAsyncProcess(process);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -872,9 +907,14 @@ void MyFrame::OnIdle(wxIdleEvent& event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnTimer(wxTimerEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxWakeUpIdle();
|
||||||
|
}
|
||||||
|
|
||||||
void MyFrame::OnProcessTerminated(MyPipedProcess *process)
|
void MyFrame::OnProcessTerminated(MyPipedProcess *process)
|
||||||
{
|
{
|
||||||
m_running.Remove(process);
|
RemoveAsyncProcess(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -919,10 +959,9 @@ bool MyPipedProcess::HasInput()
|
|||||||
{
|
{
|
||||||
bool hasInput = FALSE;
|
bool hasInput = FALSE;
|
||||||
|
|
||||||
wxInputStream& is = *GetInputStream();
|
if ( IsInputAvailable() )
|
||||||
if ( !is.Eof() )
|
|
||||||
{
|
{
|
||||||
wxTextInputStream tis(is);
|
wxTextInputStream tis(*GetInputStream());
|
||||||
|
|
||||||
// this assumes that the output is always line buffered
|
// this assumes that the output is always line buffered
|
||||||
wxString msg;
|
wxString msg;
|
||||||
@@ -933,10 +972,9 @@ bool MyPipedProcess::HasInput()
|
|||||||
hasInput = TRUE;
|
hasInput = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxInputStream& es = *GetErrorStream();
|
if ( IsErrorAvailable() )
|
||||||
if ( !es.Eof() )
|
|
||||||
{
|
{
|
||||||
wxTextInputStream tis(es);
|
wxTextInputStream tis(*GetErrorStream());
|
||||||
|
|
||||||
// this assumes that the output is always line buffered
|
// this assumes that the output is always line buffered
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
Reference in New Issue
Block a user