X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/76015a6bb79156d8af1b5e8b4b8e46b4e192d18f..821d856a610b21f2946e3283db7f79443227776e:/include/wx/unix/private/executeiohandler.h diff --git a/include/wx/unix/private/executeiohandler.h b/include/wx/unix/private/executeiohandler.h new file mode 100644 index 0000000000..ffee30b53a --- /dev/null +++ b/include/wx/unix/private/executeiohandler.h @@ -0,0 +1,137 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 +// RCS-ID: $Id$ +// 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 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() + { + // 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() { } + virtual void OnExceptionWaiting() { } + + // 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 +{ +public: + wxExecuteFDIOHandler(wxFDIODispatcher& dispatcher, + int fd, + wxStreamTempInputBuffer& buf) + : wxExecuteIOHandlerBase(fd, buf), + m_dispatcher(dispatcher) + { + dispatcher.RegisterFD(fd, this, wxFDIO_INPUT); + } + + virtual ~wxExecuteFDIOHandler() + { + DisableCallback(); + } + +private: + virtual void DoDisable() + { + 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 +{ +public: + wxExecuteEventLoopSourceHandler(int fd, wxStreamTempInputBuffer& buf) + : wxExecuteIOHandlerBase(fd, buf) + { + m_source = wxEventLoop::AddSourceForFD(fd, this, wxEVENT_SOURCE_INPUT); + } + + virtual ~wxExecuteEventLoopSourceHandler() + { + DisableCallback(); + } + +private: + virtual void DoDisable() + { + delete m_source; + m_source = NULL; + } + + wxEventLoopSource* m_source; + + wxDECLARE_NO_COPY_CLASS(wxExecuteEventLoopSourceHandler); +}; + +#endif // _WX_UNIX_PRIVATE_EXECUTEIOHANDLER_H_