1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/unix/private/sockunix.h
3 // Purpose: wxSocketImpl implementation for Unix systems
4 // Authors: Guilhem Lavaux, Vadim Zeitlin
7 // Copyright: (c) 1997 Guilhem Lavaux
8 // (c) 2008 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_UNIX_GSOCKUNX_H_
13 #define _WX_UNIX_GSOCKUNX_H_
16 #include <sys/ioctl.h>
17 #include "wx/private/fdiodispatcher.h"
19 class wxSocketImplUnix
: public wxSocketImpl
,
23 wxSocketImplUnix(wxSocketBase
& wxsocket
)
24 : wxSocketImpl(wxsocket
)
29 m_enabledCallbacks
= 0;
32 virtual wxSocketError
GetLastError() const;
34 virtual void ReenableEvents(wxSocketEventFlags flags
)
36 // enable the notifications about input/output being available again in
37 // case they were disabled by OnRead/WriteWaiting()
39 // notice that we'd like to enable the events here only if there is
40 // nothing more left on the socket right now as otherwise we're going
41 // to get a "ready for whatever" notification immediately (well, during
42 // the next event loop iteration) and disable the event back again
43 // which is rather inefficient but unfortunately doing it like this
44 // doesn't work because the existing code (e.g. src/common/sckipc.cpp)
45 // expects to keep getting notifications about the data available from
46 // the socket even if it didn't read all the data the last time, so we
47 // absolutely have to continue generating them
51 // wxFDIOHandler methods
52 virtual void OnReadWaiting();
53 virtual void OnWriteWaiting();
54 virtual void OnExceptionWaiting();
55 virtual bool IsOk() const { return m_fd
!= INVALID_SOCKET
; }
57 // Unix-specific functions used by wxSocketFDIOManager only
58 bool HasAnyEnabledCallbacks() const { return m_enabledCallbacks
!= 0; }
59 void EnableCallback(wxFDIODispatcherEntryFlags flag
)
60 { m_enabledCallbacks
|= flag
; }
61 void DisableCallback(wxFDIODispatcherEntryFlags flag
)
62 { m_enabledCallbacks
&= ~flag
; }
63 int GetEnabledCallbacks() const { return m_enabledCallbacks
; }
66 virtual void DoClose()
73 virtual void UnblockAndRegisterWithEventLoop()
76 ioctl(m_fd
, FIONBIO
, &trueArg
);
81 // enable or disable notifications for socket input/output events
82 void EnableEvents(int flags
= wxSOCKET_INPUT_FLAG
| wxSOCKET_OUTPUT_FLAG
)
83 { DoEnableEvents(flags
, true); }
84 void DisableEvents(int flags
= wxSOCKET_INPUT_FLAG
| wxSOCKET_OUTPUT_FLAG
)
85 { DoEnableEvents(flags
, false); }
87 // really enable or disable socket input/output events
88 void DoEnableEvents(int flags
, bool enable
);
91 // descriptors for input and output event notification channels associated
95 // the events which are currently enabled for this socket, combination of
96 // wxFDIO_INPUT and wxFDIO_OUTPUT values
97 int m_enabledCallbacks
;
100 // notify the associated wxSocket about a change in socket state and shut
101 // down the socket if the event is wxSOCKET_LOST
102 void OnStateChange(wxSocketNotify event
);
104 // check if there is any input available, return 1 if yes, 0 if no or -1 on
109 // give it access to our m_fds
110 friend class wxSocketFDBasedManager
;
113 // A version of wxSocketManager which uses FDs for socket IO
114 class wxSocketFDBasedManager
: public wxSocketManager
117 // no special initialization/cleanup needed when using FDs
118 virtual bool OnInit() { return true; }
119 virtual void OnExit() { }
121 virtual wxSocketImpl
*CreateSocket(wxSocketBase
& wxsocket
)
123 return new wxSocketImplUnix(wxsocket
);
127 // identifies either input or output direction
129 // NB: the values of this enum shouldn't change
136 // get the FD index corresponding to the given wxSocketNotify
137 SocketDir
GetDirForEvent(wxSocketImpl
*socket
, wxSocketNotify event
)
142 wxFAIL_MSG( "unknown socket event" );
143 return FD_INPUT
; // we must return something
146 wxFAIL_MSG( "unexpected socket event" );
147 return FD_INPUT
; // as above
152 case wxSOCKET_OUTPUT
:
155 case wxSOCKET_CONNECTION
:
156 // for server sockets we're interested in events indicating
157 // that a new connection is pending, i.e. that accept() will
158 // succeed and this is indicated by socket becoming ready for
159 // reading, while for the other ones we're interested in the
160 // completion of non-blocking connect() which is indicated by
161 // the socket becoming ready for writing
162 return socket
->IsServer() ? FD_INPUT
: FD_OUTPUT
;
166 // access the FDs we store
167 int& FD(wxSocketImplUnix
*socket
, SocketDir d
)
169 return socket
->m_fds
[d
];
173 // Common base class for all ports using X11-like (and hence implemented in
174 // X11, Motif and GTK) AddInput() and RemoveInput() functions
175 class wxSocketInputBasedManager
: public wxSocketFDBasedManager
178 virtual void Install_Callback(wxSocketImpl
*socket_
, wxSocketNotify event
)
180 wxSocketImplUnix
* const
181 socket
= static_cast<wxSocketImplUnix
*>(socket_
);
183 wxCHECK_RET( socket
->m_fd
!= -1,
184 "shouldn't be called on invalid socket" );
186 const SocketDir d
= GetDirForEvent(socket
, event
);
188 int& fd
= FD(socket
, d
);
192 fd
= AddInput(socket
, socket
->m_fd
, d
);
195 virtual void Uninstall_Callback(wxSocketImpl
*socket_
, wxSocketNotify event
)
197 wxSocketImplUnix
* const
198 socket
= static_cast<wxSocketImplUnix
*>(socket_
);
200 const SocketDir d
= GetDirForEvent(socket
, event
);
202 int& fd
= FD(socket
, d
);
211 // these functions map directly to XtAdd/RemoveInput() or
212 // gdk_input_add/remove()
213 virtual int AddInput(wxSocketImplUnix
*handler
, int fd
, SocketDir d
) = 0;
214 virtual void RemoveInput(int fd
) = 0;
217 #endif /* _WX_UNIX_GSOCKUNX_H_ */