]> git.saurik.com Git - wxWidgets.git/blob - include/wx/unix/private/sockunix.h
don't remove/add back the socket to the list of inputs monitored by the event loop...
[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 wxSocketError GetLastError() const;
33
34 virtual void Shutdown();
35
36 virtual int Read(void *buffer, int size);
37 virtual int Write(const void *buffer, int size);
38
39 // wxFDIOHandler methods
40 virtual void OnReadWaiting();
41 virtual void OnWriteWaiting();
42 virtual void OnExceptionWaiting();
43
44 // Unix-specific functions
45 bool HasAnyEnabledCallbacks() const { return m_enabledCallbacks != 0; }
46 void EnableCallback(wxFDIODispatcherEntryFlags flag)
47 { m_enabledCallbacks |= flag; }
48 void DisableCallback(wxFDIODispatcherEntryFlags flag)
49 { m_enabledCallbacks &= ~flag; }
50 int GetEnabledCallbacks() const { return m_enabledCallbacks; }
51
52 private:
53 virtual void DoClose()
54 {
55 DisableEvents();
56
57 close(m_fd);
58 }
59
60 virtual void UnblockAndRegisterWithEventLoop()
61 {
62 int trueArg = 1;
63 ioctl(m_fd, FIONBIO, &trueArg);
64
65 EnableEvents();
66 }
67
68 // enable or disable notifications for socket input/output events
69 void EnableEvents() { DoEnableEvents(true); }
70 void DisableEvents() { DoEnableEvents(false); }
71
72 // really enable or disable socket input/output events
73 void DoEnableEvents(bool enable);
74
75
76 int Recv_Stream(void *buffer, int size);
77 int Recv_Dgram(void *buffer, int size);
78 int Send_Stream(const void *buffer, int size);
79 int Send_Dgram(const void *buffer, int size);
80
81
82 protected:
83 // descriptors for input and output event notification channels associated
84 // with the socket
85 int m_fds[2];
86
87 // the events which are currently enabled for this socket, combination of
88 // wxFDIO_INPUT and wxFDIO_OUTPUT values
89 int m_enabledCallbacks;
90
91 private:
92 // notify the associated wxSocket about a change in socket state and shut
93 // down the socket if the event is wxSOCKET_LOST
94 void OnStateChange(wxSocketNotify event);
95
96 // give it access to our m_fds
97 friend class wxSocketFDBasedManager;
98 };
99
100 // A version of wxSocketManager which uses FDs for socket IO
101 class wxSocketFDBasedManager : public wxSocketManager
102 {
103 public:
104 // no special initialization/cleanup needed when using FDs
105 virtual bool OnInit() { return true; }
106 virtual void OnExit() { }
107
108 protected:
109 // identifies either input or output direction
110 //
111 // NB: the values of this enum shouldn't change
112 enum SocketDir
113 {
114 FD_INPUT,
115 FD_OUTPUT
116 };
117
118 // get the FD index corresponding to the given wxSocketNotify
119 SocketDir GetDirForEvent(wxSocketImpl *socket, wxSocketNotify event)
120 {
121 switch ( event )
122 {
123 default:
124 wxFAIL_MSG( "unexpected socket event" );
125 // fall through
126
127 case wxSOCKET_LOST:
128 // fall through
129
130 case wxSOCKET_INPUT:
131 return FD_INPUT;
132
133 case wxSOCKET_OUTPUT:
134 return FD_OUTPUT;
135
136 case wxSOCKET_CONNECTION:
137 // FIXME: explain this?
138 return socket->IsServer() ? FD_INPUT : FD_OUTPUT;
139 }
140 }
141
142 // access the FDs we store
143 int& FD(wxSocketImplUnix *socket, SocketDir d)
144 {
145 return socket->m_fds[d];
146 }
147 };
148
149 // Common base class for all ports using X11-like (and hence implemented in
150 // X11, Motif and GTK) AddInput() and RemoveInput() functions
151 class wxSocketInputBasedManager : public wxSocketFDBasedManager
152 {
153 public:
154 virtual void Install_Callback(wxSocketImpl *socket_, wxSocketNotify event)
155 {
156 wxSocketImplUnix * const
157 socket = static_cast<wxSocketImplUnix *>(socket_);
158
159 wxCHECK_RET( socket->m_fd != -1,
160 "shouldn't be called on invalid socket" );
161
162 const SocketDir d = GetDirForEvent(socket, event);
163
164 int& fd = FD(socket, d);
165 if ( fd != -1 )
166 RemoveInput(fd);
167
168 fd = AddInput(socket, socket->m_fd, d);
169 }
170
171 virtual void Uninstall_Callback(wxSocketImpl *socket_, wxSocketNotify event)
172 {
173 wxSocketImplUnix * const
174 socket = static_cast<wxSocketImplUnix *>(socket_);
175
176 const SocketDir d = GetDirForEvent(socket, event);
177
178 int& fd = FD(socket, d);
179 if ( fd != -1 )
180 {
181 RemoveInput(fd);
182 fd = -1;
183 }
184 }
185
186 private:
187 // these functions map directly to XtAdd/RemoveInput() or
188 // gdk_input_add/remove()
189 virtual int AddInput(wxFDIOHandler *handler, int fd, SocketDir d) = 0;
190 virtual void RemoveInput(int fd) = 0;
191 };
192
193 #endif /* _WX_UNIX_GSOCKUNX_H_ */