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