X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ebbf7407644c407815de10284a49042f602101c1..9a6aafe0039fef580ca1bfcf0e87c1ba8e2953ba:/src/common/socket.cpp?ds=sidebyside diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 88937119b1..abe4f83810 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -42,6 +42,7 @@ #include "wx/stopwatch.h" #include "wx/thread.h" #include "wx/evtloop.h" +#include "wx/link.h" #include "wx/private/fd.h" #include "wx/private/socket.h" @@ -57,10 +58,12 @@ // this should cover all the current Unix systems (Windows never sends any // signals anyhow) but if we find one that has neither we should explicitly // ignore SIGPIPE for it +// OpenVMS has neither MSG_NOSIGNAL nor SO_NOSIGPIPE. However the socket sample +// seems to work. Not sure if problems will show up on OpenVMS using sockets. #ifdef MSG_NOSIGNAL #define wxSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL #else // MSG_NOSIGNAL not available (BSD including OS X) - #if defined(__UNIX__) && !defined(SO_NOSIGPIPE) + #if defined(__UNIX__) && !defined(SO_NOSIGPIPE) && !defined( __VMS ) #error "Writing to socket could generate unhandled SIGPIPE." #error "Please post information about your system to wx-dev." #endif @@ -76,6 +79,9 @@ WX_CHECK_BUILD_OPTIONS("wxNet") // macros and constants // -------------------------------------------------------------------------- +// event +wxDEFINE_EVENT(wxEVT_SOCKET, wxSocketEvent); + // discard buffer #define MAX_DISCARD_SIZE (10 * 1024) @@ -764,7 +770,8 @@ void wxSocketBase::Init() { // this Initialize() will be undone by wxSocketModule::OnExit(), all // the other calls to it should be matched by a call to Shutdown() - Initialize(); + if (!Initialize()) + wxLogError("Cannot initialize wxSocketBase"); } } @@ -1321,6 +1328,20 @@ wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags) eventLoop = NULL; } + // Make sure the events we're interested in are enabled before waiting for + // them: this is really necessary here as otherwise this could happen: + // 1. DoRead(wxSOCKET_WAITALL) is called + // 2. There is nothing to read so DoWait(wxSOCKET_INPUT_FLAG) is called + // 3. Some, but not all data appears, wxSocketImplUnix::OnReadWaiting() + // is called and wxSOCKET_INPUT_FLAG events are disabled in it + // 4. Because of wxSOCKET_WAITALL we call DoWait() again but the events + // are still disabled and we block forever + // + // More elegant solution would be nice but for now simply re-enabling the + // events here will do + m_impl->ReenableEvents(flags & (wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG)); + + // Wait until we receive the event we're waiting for or the timeout expires // (but note that we always execute the loop at least once, even if timeout // is 0 as this is used for polling) @@ -1563,6 +1584,15 @@ void wxSocketBase::OnRequest(wxSocketNotify notification) // send the wx event if enabled and we're interested in it if ( m_notify && (m_eventmask & flag) && m_handler ) { + // don't generate the events when we're inside DoWait() called from our + // own code as we are going to consume the data that has just become + // available ourselves and the user code won't see it at all + if ( (notification == wxSOCKET_INPUT && m_reading) || + (notification == wxSOCKET_OUTPUT && m_writing) ) + { + return; + } + wxSocketEvent event(m_id); event.m_event = notification; event.m_clientData = m_clientData; @@ -1974,4 +2004,11 @@ private: IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule) +#if defined(wxUSE_SELECT_DISPATCHER) && wxUSE_SELECT_DISPATCHER +// NOTE: we need to force linking against socketiohandler.cpp otherwise in +// static builds of wxWidgets the ManagerSetter::ManagerSetter ctor +// contained there wouldn't be ever called +wxFORCE_LINK_MODULE( socketiohandler ) +#endif + #endif // wxUSE_SOCKETS