remove m_use_events from Unix wxSocket implementation, we always need asynchronous...
[wxWidgets.git] / include / wx / unix / private / sockunix.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/unix/private/sockunix.h
3 // Purpose: wxSocketImpl implementation for Unix systems
4 // Authors: Guilhem Lavaux, Vadim Zeitlin
5 // Created: April 1997
6 // RCS-ID: $Id$
7 // Copyright: (c) 1997 Guilhem Lavaux
8 // (c) 2008 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_UNIX_GSOCKUNX_H_
13 #define _WX_UNIX_GSOCKUNX_H_
14
15 #include <unistd.h>
16 #include <sys/ioctl.h>
17 #include "wx/private/fdiodispatcher.h"
18
19 class wxSocketImplUnix : public wxSocketImpl,
20 public wxFDIOHandler
21 {
22 public:
23 wxSocketImplUnix(wxSocketBase& wxsocket)
24 : wxSocketImpl(wxsocket)
25 {
26 m_fds[0] =
27 m_fds[1] = -1;
28
29 m_enabledCallbacks = 0;
30 }
31
32 virtual void Shutdown();
33 virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket);
34
35 int Read(void *buffer, int size);
36 int Write(const void *buffer, int size);
37
38 // wxFDIOHandler methods
39 virtual void OnReadWaiting();
40 virtual void OnWriteWaiting();
41 virtual void OnExceptionWaiting();
42
43 // Unix-specific functions
44 bool HasAnyEnabledCallbacks() const { return m_enabledCallbacks != 0; }
45 void EnableCallback(wxFDIODispatcherEntryFlags flag)
46 { m_enabledCallbacks |= flag; }
47 void DisableCallback(wxFDIODispatcherEntryFlags flag)
48 { m_enabledCallbacks &= ~flag; }
49 int GetEnabledCallbacks() const { return m_enabledCallbacks; }
50
51 private:
52 virtual wxSocketError DoHandleConnect(int ret);
53 virtual void DoClose()
54 {
55 wxSocketManager * const manager = wxSocketManager::Get();
56 if ( manager )
57 {
58 manager->Uninstall_Callback(this, wxSOCKET_INPUT);
59 manager->Uninstall_Callback(this, wxSOCKET_OUTPUT);
60 }
61
62 close(m_fd);
63 }
64
65 virtual void UnblockAndRegisterWithEventLoop()
66 {
67 int trueArg = 1;
68 ioctl(m_fd, FIONBIO, &trueArg);
69
70 EnableEvents();
71 }
72
73 // enable or disable notifications for socket input/output events
74 void EnableEvents() { DoEnableEvents(true); }
75 void DisableEvents() { DoEnableEvents(false);
76 }
77
78 // really enable or disable socket input/output events
79 void DoEnableEvents(bool enable);
80
81
82 // enable or disable events for the given event
83 //
84 // notice that these functions also update m_detected: EnableEvent() clears
85 // the corresponding bit in it and DisableEvent() sets it
86 void EnableEvent(wxSocketNotify event);
87 void DisableEvent(wxSocketNotify event);
88
89 int Recv_Stream(void *buffer, int size);
90 int Recv_Dgram(void *buffer, int size);
91 int Send_Stream(const void *buffer, int size);
92 int Send_Dgram(const void *buffer, int size);
93
94
95 protected:
96 // descriptors for input and output event notification channels associated
97 // with the socket
98 int m_fds[2];
99
100 // the events which are currently enabled for this socket, combination of
101 // wxFDIO_INPUT and wxFDIO_OUTPUT values
102 //
103 // TODO: this overlaps with m_detected but the semantics of the latter are
104 // very unclear so I don't dare to remove it right now
105 int m_enabledCallbacks;
106
107 private:
108 // notify the associated wxSocket about a change in socket state and shut
109 // down the socket if the event is wxSOCKET_LOST
110 void OnStateChange(wxSocketNotify event);
111
112 // give it access to our m_fds
113 friend class wxSocketFDBasedManager;
114 };
115
116 // A version of wxSocketManager which uses FDs for socket IO
117 class wxSocketFDBasedManager : public wxSocketManager
118 {
119 public:
120 // no special initialization/cleanup needed when using FDs
121 virtual bool OnInit() { return true; }
122 virtual void OnExit() { }
123
124 protected:
125 // identifies either input or output direction
126 //
127 // NB: the values of this enum shouldn't change
128 enum SocketDir
129 {
130 FD_INPUT,
131 FD_OUTPUT
132 };
133
134 // get the FD index corresponding to the given wxSocketNotify
135 SocketDir GetDirForEvent(wxSocketImpl *socket, wxSocketNotify event)
136 {
137 switch ( event )
138 {
139 default:
140 wxFAIL_MSG( "unexpected socket event" );
141 // fall through
142
143 case wxSOCKET_LOST:
144 // fall through
145
146 case wxSOCKET_INPUT:
147 return FD_INPUT;
148
149 case wxSOCKET_OUTPUT:
150 return FD_OUTPUT;
151
152 case wxSOCKET_CONNECTION:
153 // FIXME: explain this?
154 return socket->m_server ? FD_INPUT : FD_OUTPUT;
155 }
156 }
157
158 // access the FDs we store
159 int& FD(wxSocketImplUnix *socket, SocketDir d)
160 {
161 return socket->m_fds[d];
162 }
163 };
164
165 // Common base class for all ports using X11-like (and hence implemented in
166 // X11, Motif and GTK) AddInput() and RemoveInput() functions
167 class wxSocketInputBasedManager : public wxSocketFDBasedManager
168 {
169 public:
170 virtual void Install_Callback(wxSocketImpl *socket_, wxSocketNotify event)
171 {
172 wxSocketImplUnix * const
173 socket = static_cast<wxSocketImplUnix *>(socket_);
174
175 wxCHECK_RET( socket->m_fd != -1,
176 "shouldn't be called on invalid socket" );
177
178 const SocketDir d = GetDirForEvent(socket, event);
179
180 int& fd = FD(socket, d);
181 if ( fd != -1 )
182 RemoveInput(fd);
183
184 fd = AddInput(socket, socket->m_fd, d);
185 }
186
187 virtual void Uninstall_Callback(wxSocketImpl *socket_, wxSocketNotify event)
188 {
189 wxSocketImplUnix * const
190 socket = static_cast<wxSocketImplUnix *>(socket_);
191
192 const SocketDir d = GetDirForEvent(socket, event);
193
194 int& fd = FD(socket, d);
195 if ( fd != -1 )
196 {
197 RemoveInput(fd);
198 fd = -1;
199 }
200 }
201
202 private:
203 // these functions map directly to XtAdd/RemoveInput() or
204 // gdk_input_add/remove()
205 virtual int AddInput(wxFDIOHandler *handler, int fd, SocketDir d) = 0;
206 virtual void RemoveInput(int fd) = 0;
207 };
208
209 #endif /* _WX_UNIX_GSOCKUNX_H_ */