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