137 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        wx/unix/private/executeiohandler.h
 | 
						|
// Purpose:     IO handler class for the FD used by wxExecute() under Unix
 | 
						|
// Author:      Rob Bresalier, Vadim Zeitlin
 | 
						|
// Created:     2013-01-06
 | 
						|
// Copyright:   (c) 2013 Rob Bresalier, Vadim Zeitlin
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifndef _WX_UNIX_PRIVATE_EXECUTEIOHANDLER_H_
 | 
						|
#define _WX_UNIX_PRIVATE_EXECUTEIOHANDLER_H_
 | 
						|
 | 
						|
#include "wx/private/streamtempinput.h"
 | 
						|
 | 
						|
// This class handles IO events on the pipe FD connected to the child process
 | 
						|
// stdout/stderr and is used by wxExecute().
 | 
						|
//
 | 
						|
// Currently it can derive from either wxEventLoopSourceHandler or
 | 
						|
// wxFDIOHandler depending on the kind of dispatcher/event loop it is used
 | 
						|
// with. In the future, when we get rid of wxFDIOHandler entirely, it will
 | 
						|
// derive from wxEventLoopSourceHandler only.
 | 
						|
template <class T>
 | 
						|
class wxExecuteIOHandlerBase : public T
 | 
						|
{
 | 
						|
public:
 | 
						|
    wxExecuteIOHandlerBase(int fd, wxStreamTempInputBuffer& buf)
 | 
						|
        : m_fd(fd),
 | 
						|
          m_buf(buf)
 | 
						|
    {
 | 
						|
        m_callbackDisabled = false;
 | 
						|
    }
 | 
						|
 | 
						|
    // Called when the associated descriptor is available for reading.
 | 
						|
    virtual void OnReadWaiting() wxOVERRIDE
 | 
						|
    {
 | 
						|
        // Sync process, process all data coming at us from the pipe so that
 | 
						|
        // the pipe does not get full and cause a deadlock situation.
 | 
						|
        m_buf.Update();
 | 
						|
 | 
						|
        if ( m_buf.Eof() )
 | 
						|
            DisableCallback();
 | 
						|
    }
 | 
						|
 | 
						|
    // These methods are never called as we only monitor the associated FD for
 | 
						|
    // reading, but we still must implement them as they're pure virtual in the
 | 
						|
    // base class.
 | 
						|
    virtual void OnWriteWaiting() wxOVERRIDE { }
 | 
						|
    virtual void OnExceptionWaiting() wxOVERRIDE { }
 | 
						|
 | 
						|
    // Disable any future calls to our OnReadWaiting(), can be called when
 | 
						|
    // we're sure that no more input is forthcoming.
 | 
						|
    void DisableCallback()
 | 
						|
    {
 | 
						|
        if ( !m_callbackDisabled )
 | 
						|
        {
 | 
						|
            m_callbackDisabled = true;
 | 
						|
 | 
						|
            DoDisable();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
protected:
 | 
						|
    const int m_fd;
 | 
						|
 | 
						|
private:
 | 
						|
    virtual void DoDisable() = 0;
 | 
						|
 | 
						|
    wxStreamTempInputBuffer& m_buf;
 | 
						|
 | 
						|
    // If true, DisableCallback() had been already called.
 | 
						|
    bool m_callbackDisabled;
 | 
						|
 | 
						|
    wxDECLARE_NO_COPY_CLASS(wxExecuteIOHandlerBase);
 | 
						|
};
 | 
						|
 | 
						|
// This is the version used with wxFDIODispatcher, which must be passed to the
 | 
						|
// ctor in order to register this handler with it.
 | 
						|
class wxExecuteFDIOHandler : public wxExecuteIOHandlerBase<wxFDIOHandler>
 | 
						|
{
 | 
						|
public:
 | 
						|
    wxExecuteFDIOHandler(wxFDIODispatcher& dispatcher,
 | 
						|
                         int fd,
 | 
						|
                         wxStreamTempInputBuffer& buf)
 | 
						|
        : wxExecuteIOHandlerBase<wxFDIOHandler>(fd, buf),
 | 
						|
          m_dispatcher(dispatcher)
 | 
						|
    {
 | 
						|
        dispatcher.RegisterFD(fd, this, wxFDIO_INPUT);
 | 
						|
    }
 | 
						|
 | 
						|
    virtual ~wxExecuteFDIOHandler()
 | 
						|
    {
 | 
						|
        DisableCallback();
 | 
						|
    }
 | 
						|
 | 
						|
private:
 | 
						|
    virtual void DoDisable() wxOVERRIDE
 | 
						|
    {
 | 
						|
        m_dispatcher.UnregisterFD(m_fd);
 | 
						|
    }
 | 
						|
 | 
						|
    wxFDIODispatcher& m_dispatcher;
 | 
						|
 | 
						|
    wxDECLARE_NO_COPY_CLASS(wxExecuteFDIOHandler);
 | 
						|
};
 | 
						|
 | 
						|
// And this is the version used with an event loop. As AddSourceForFD() is
 | 
						|
// static, we don't require passing the event loop to the ctor but an event
 | 
						|
// loop must be running to handle our events.
 | 
						|
class wxExecuteEventLoopSourceHandler
 | 
						|
    : public wxExecuteIOHandlerBase<wxEventLoopSourceHandler>
 | 
						|
{
 | 
						|
public:
 | 
						|
    wxExecuteEventLoopSourceHandler(int fd, wxStreamTempInputBuffer& buf)
 | 
						|
        : wxExecuteIOHandlerBase<wxEventLoopSourceHandler>(fd, buf)
 | 
						|
    {
 | 
						|
        m_source = wxEventLoop::AddSourceForFD(fd, this, wxEVENT_SOURCE_INPUT);
 | 
						|
    }
 | 
						|
 | 
						|
    virtual ~wxExecuteEventLoopSourceHandler()
 | 
						|
    {
 | 
						|
        DisableCallback();
 | 
						|
    }
 | 
						|
 | 
						|
private:
 | 
						|
    virtual void DoDisable() wxOVERRIDE
 | 
						|
    {
 | 
						|
        delete m_source;
 | 
						|
        m_source = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    wxEventLoopSource* m_source;
 | 
						|
 | 
						|
    wxDECLARE_NO_COPY_CLASS(wxExecuteEventLoopSourceHandler);
 | 
						|
};
 | 
						|
 | 
						|
#endif // _WX_UNIX_PRIVATE_EXECUTEIOHANDLER_H_
 |