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:
Vadim Zeitlin
2002-08-21 19:45:59 +00:00
parent b767f77178
commit 92a2a7eb81

View File

@@ -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;