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