X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2b036c4b2365723b4c52890bd4c2f6bde20bbc00..7344108e8a129a3f9b4df5ab0f98a1713db03b89:/include/wx/unix/private/sockunix.h diff --git a/include/wx/unix/private/sockunix.h b/include/wx/unix/private/sockunix.h index ac36bb315b..ea3006215f 100644 --- a/include/wx/unix/private/sockunix.h +++ b/include/wx/unix/private/sockunix.h @@ -14,7 +14,15 @@ #include #include -#include "wx/private/fdiodispatcher.h" + +// Under older (Open)Solaris versions FIONBIO is declared in this header only. +// In the newer versions it's included by sys/ioctl.h but it's simpler to just +// include it always instead of testing for whether it is or not. +#ifdef __SOLARIS__ + #include +#endif + +#include "wx/private/fdiomanager.h" class wxSocketImplUnix : public wxSocketImpl, public wxFDIOHandler @@ -25,39 +33,37 @@ public: { m_fds[0] = m_fds[1] = -1; - - m_enabledCallbacks = 0; } virtual wxSocketError GetLastError() const; - virtual void Shutdown(); - - virtual int Read(void *buffer, int size); - virtual int Write(const void *buffer, int size); + virtual void ReenableEvents(wxSocketEventFlags flags) + { + // enable the notifications about input/output being available again in + // case they were disabled by OnRead/WriteWaiting() + // + // notice that we'd like to enable the events here only if there is + // nothing more left on the socket right now as otherwise we're going + // to get a "ready for whatever" notification immediately (well, during + // the next event loop iteration) and disable the event back again + // which is rather inefficient but unfortunately doing it like this + // doesn't work because the existing code (e.g. src/common/sckipc.cpp) + // expects to keep getting notifications about the data available from + // the socket even if it didn't read all the data the last time, so we + // absolutely have to continue generating them + EnableEvents(flags); + } // wxFDIOHandler methods virtual void OnReadWaiting(); virtual void OnWriteWaiting(); virtual void OnExceptionWaiting(); - - // Unix-specific functions - bool HasAnyEnabledCallbacks() const { return m_enabledCallbacks != 0; } - void EnableCallback(wxFDIODispatcherEntryFlags flag) - { m_enabledCallbacks |= flag; } - void DisableCallback(wxFDIODispatcherEntryFlags flag) - { m_enabledCallbacks &= ~flag; } - int GetEnabledCallbacks() const { return m_enabledCallbacks; } + virtual bool IsOk() const { return m_fd != INVALID_SOCKET; } private: virtual void DoClose() { - wxSocketManager * const manager = wxSocketManager::Get(); - if ( manager ) - { - manager->Uninstall_Callback(this, wxSOCKET_INPUT); - manager->Uninstall_Callback(this, wxSOCKET_OUTPUT); - } + DisableEvents(); close(m_fd); } @@ -71,139 +77,69 @@ private: } // enable or disable notifications for socket input/output events - void EnableEvents() { DoEnableEvents(true); } - void DisableEvents() { DoEnableEvents(false); - } + void EnableEvents(int flags = wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG) + { DoEnableEvents(flags, true); } + void DisableEvents(int flags = wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG) + { DoEnableEvents(flags, false); } // really enable or disable socket input/output events - void DoEnableEvents(bool enable); - - - // enable or disable events for the given event - // - // notice that these functions also update m_detected: EnableEvent() clears - // the corresponding bit in it and DisableEvent() sets it - void EnableEvent(wxSocketNotify event); - void DisableEvent(wxSocketNotify event); - - int Recv_Stream(void *buffer, int size); - int Recv_Dgram(void *buffer, int size); - int Send_Stream(const void *buffer, int size); - int Send_Dgram(const void *buffer, int size); - + void DoEnableEvents(int flags, bool enable); protected: // descriptors for input and output event notification channels associated // with the socket int m_fds[2]; - // the events which are currently enabled for this socket, combination of - // wxFDIO_INPUT and wxFDIO_OUTPUT values - // - // TODO: this overlaps with m_detected but the semantics of the latter are - // very unclear so I don't dare to remove it right now - int m_enabledCallbacks; - private: // notify the associated wxSocket about a change in socket state and shut // down the socket if the event is wxSOCKET_LOST void OnStateChange(wxSocketNotify event); + // check if there is any input available, return 1 if yes, 0 if no or -1 on + // error + int CheckForInput(); + + // give it access to our m_fds friend class wxSocketFDBasedManager; }; -// A version of wxSocketManager which uses FDs for socket IO +// A version of wxSocketManager which uses FDs for socket IO: it is used by +// Unix console applications and some X11-like ports (wxGTK and wxMotif but not +// wxX11 currently) which implement their own port-specific wxFDIOManagers class wxSocketFDBasedManager : public wxSocketManager { public: - // no special initialization/cleanup needed when using FDs - virtual bool OnInit() { return true; } - virtual void OnExit() { } - -protected: - // identifies either input or output direction - // - // NB: the values of this enum shouldn't change - enum SocketDir + wxSocketFDBasedManager() { - FD_INPUT, - FD_OUTPUT - }; - - // get the FD index corresponding to the given wxSocketNotify - SocketDir GetDirForEvent(wxSocketImpl *socket, wxSocketNotify event) - { - switch ( event ) - { - default: - wxFAIL_MSG( "unexpected socket event" ); - // fall through + m_fdioManager = NULL; + } - case wxSOCKET_LOST: - // fall through + virtual bool OnInit(); + virtual void OnExit() { } - case wxSOCKET_INPUT: - return FD_INPUT; + virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket) + { + return new wxSocketImplUnix(wxsocket); + } - case wxSOCKET_OUTPUT: - return FD_OUTPUT; + virtual void Install_Callback(wxSocketImpl *socket_, wxSocketNotify event); + virtual void Uninstall_Callback(wxSocketImpl *socket_, wxSocketNotify event); - case wxSOCKET_CONNECTION: - // FIXME: explain this? - return socket->IsServer() ? FD_INPUT : FD_OUTPUT; - } - } +protected: + // get the FD index corresponding to the given wxSocketNotify + wxFDIOManager::Direction + GetDirForEvent(wxSocketImpl *socket, wxSocketNotify event); // access the FDs we store - int& FD(wxSocketImplUnix *socket, SocketDir d) + int& FD(wxSocketImplUnix *socket, wxFDIOManager::Direction d) { return socket->m_fds[d]; } -}; - -// Common base class for all ports using X11-like (and hence implemented in -// X11, Motif and GTK) AddInput() and RemoveInput() functions -class wxSocketInputBasedManager : public wxSocketFDBasedManager -{ -public: - virtual void Install_Callback(wxSocketImpl *socket_, wxSocketNotify event) - { - wxSocketImplUnix * const - socket = static_cast(socket_); - wxCHECK_RET( socket->m_fd != -1, - "shouldn't be called on invalid socket" ); + wxFDIOManager *m_fdioManager; - const SocketDir d = GetDirForEvent(socket, event); - - int& fd = FD(socket, d); - if ( fd != -1 ) - RemoveInput(fd); - - fd = AddInput(socket, socket->m_fd, d); - } - - virtual void Uninstall_Callback(wxSocketImpl *socket_, wxSocketNotify event) - { - wxSocketImplUnix * const - socket = static_cast(socket_); - - const SocketDir d = GetDirForEvent(socket, event); - - int& fd = FD(socket, d); - if ( fd != -1 ) - { - RemoveInput(fd); - fd = -1; - } - } - -private: - // these functions map directly to XtAdd/RemoveInput() or - // gdk_input_add/remove() - virtual int AddInput(wxFDIOHandler *handler, int fd, SocketDir d) = 0; - virtual void RemoveInput(int fd) = 0; + wxDECLARE_NO_COPY_CLASS(wxSocketFDBasedManager); }; #endif /* _WX_UNIX_GSOCKUNX_H_ */