executeiohandler.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/unix/private/executeiohandler.h
  3. // Purpose: IO handler class for the FD used by wxExecute() under Unix
  4. // Author: Rob Bresalier, Vadim Zeitlin
  5. // Created: 2013-01-06
  6. // Copyright: (c) 2013 Rob Bresalier, Vadim Zeitlin
  7. // Licence: wxWindows licence
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #ifndef _WX_UNIX_PRIVATE_EXECUTEIOHANDLER_H_
  10. #define _WX_UNIX_PRIVATE_EXECUTEIOHANDLER_H_
  11. #include "wx/private/streamtempinput.h"
  12. // This class handles IO events on the pipe FD connected to the child process
  13. // stdout/stderr and is used by wxExecute().
  14. //
  15. // Currently it can derive from either wxEventLoopSourceHandler or
  16. // wxFDIOHandler depending on the kind of dispatcher/event loop it is used
  17. // with. In the future, when we get rid of wxFDIOHandler entirely, it will
  18. // derive from wxEventLoopSourceHandler only.
  19. template <class T>
  20. class wxExecuteIOHandlerBase : public T
  21. {
  22. public:
  23. wxExecuteIOHandlerBase(int fd, wxStreamTempInputBuffer& buf)
  24. : m_fd(fd),
  25. m_buf(buf)
  26. {
  27. m_callbackDisabled = false;
  28. }
  29. // Called when the associated descriptor is available for reading.
  30. virtual void OnReadWaiting()
  31. {
  32. // Sync process, process all data coming at us from the pipe so that
  33. // the pipe does not get full and cause a deadlock situation.
  34. m_buf.Update();
  35. if ( m_buf.Eof() )
  36. DisableCallback();
  37. }
  38. // These methods are never called as we only monitor the associated FD for
  39. // reading, but we still must implement them as they're pure virtual in the
  40. // base class.
  41. virtual void OnWriteWaiting() { }
  42. virtual void OnExceptionWaiting() { }
  43. // Disable any future calls to our OnReadWaiting(), can be called when
  44. // we're sure that no more input is forthcoming.
  45. void DisableCallback()
  46. {
  47. if ( !m_callbackDisabled )
  48. {
  49. m_callbackDisabled = true;
  50. DoDisable();
  51. }
  52. }
  53. protected:
  54. const int m_fd;
  55. private:
  56. virtual void DoDisable() = 0;
  57. wxStreamTempInputBuffer& m_buf;
  58. // If true, DisableCallback() had been already called.
  59. bool m_callbackDisabled;
  60. wxDECLARE_NO_COPY_CLASS(wxExecuteIOHandlerBase);
  61. };
  62. // This is the version used with wxFDIODispatcher, which must be passed to the
  63. // ctor in order to register this handler with it.
  64. class wxExecuteFDIOHandler : public wxExecuteIOHandlerBase<wxFDIOHandler>
  65. {
  66. public:
  67. wxExecuteFDIOHandler(wxFDIODispatcher& dispatcher,
  68. int fd,
  69. wxStreamTempInputBuffer& buf)
  70. : wxExecuteIOHandlerBase<wxFDIOHandler>(fd, buf),
  71. m_dispatcher(dispatcher)
  72. {
  73. dispatcher.RegisterFD(fd, this, wxFDIO_INPUT);
  74. }
  75. virtual ~wxExecuteFDIOHandler()
  76. {
  77. DisableCallback();
  78. }
  79. private:
  80. virtual void DoDisable()
  81. {
  82. m_dispatcher.UnregisterFD(m_fd);
  83. }
  84. wxFDIODispatcher& m_dispatcher;
  85. wxDECLARE_NO_COPY_CLASS(wxExecuteFDIOHandler);
  86. };
  87. // And this is the version used with an event loop. As AddSourceForFD() is
  88. // static, we don't require passing the event loop to the ctor but an event
  89. // loop must be running to handle our events.
  90. class wxExecuteEventLoopSourceHandler
  91. : public wxExecuteIOHandlerBase<wxEventLoopSourceHandler>
  92. {
  93. public:
  94. wxExecuteEventLoopSourceHandler(int fd, wxStreamTempInputBuffer& buf)
  95. : wxExecuteIOHandlerBase<wxEventLoopSourceHandler>(fd, buf)
  96. {
  97. m_source = wxEventLoop::AddSourceForFD(fd, this, wxEVENT_SOURCE_INPUT);
  98. }
  99. virtual ~wxExecuteEventLoopSourceHandler()
  100. {
  101. DisableCallback();
  102. }
  103. private:
  104. virtual void DoDisable()
  105. {
  106. delete m_source;
  107. m_source = NULL;
  108. }
  109. wxEventLoopSource* m_source;
  110. wxDECLARE_NO_COPY_CLASS(wxExecuteEventLoopSourceHandler);
  111. };
  112. #endif // _WX_UNIX_PRIVATE_EXECUTEIOHANDLER_H_