From: Vadim Zeitlin Date: Sun, 3 Feb 2008 23:59:09 +0000 (+0000) Subject: undid change to GSocket::Select() done in r50831, do call select() here (part of... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/cf86dc50e0a5f20a9c696e49942cb50c761aa86f undid change to GSocket::Select() done in r50831, do call select() here (part of patch 1833150) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51536 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/unix/gsocket.cpp b/src/unix/gsocket.cpp index 8bcb88fb0a..08dbb42dfa 100644 --- a/src/unix/gsocket.cpp +++ b/src/unix/gsocket.cpp @@ -1296,7 +1296,99 @@ GSocketEventFlags GSocket::Select(GSocketEventFlags flags) { assert(this); - return flags & m_detected; + GSocketEventFlags result = 0; + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + struct timeval tv; + + if (m_fd == -1) + return (GSOCK_LOST_FLAG & flags); + + /* Do not use a static struct, Linux can garble it */ + tv.tv_sec = 0; + tv.tv_usec = 0; + + wxFD_ZERO(&readfds); + wxFD_ZERO(&writefds); + wxFD_ZERO(&exceptfds); + wxFD_SET(m_fd, &readfds); + if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG) + wxFD_SET(m_fd, &writefds); + wxFD_SET(m_fd, &exceptfds); + + /* Check 'sticky' CONNECTION flag first */ + result |= GSOCK_CONNECTION_FLAG & m_detected; + + /* If we have already detected a LOST event, then don't try + * to do any further processing. + */ + if ((m_detected & GSOCK_LOST_FLAG) != 0) + { + m_establishing = false; + return (GSOCK_LOST_FLAG & flags); + } + + /* Try select now */ + if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0) + { + /* What to do here? */ + return (result & flags); + } + + /* Check for exceptions and errors */ + if (wxFD_ISSET(m_fd, &exceptfds)) + { + m_establishing = false; + m_detected = GSOCK_LOST_FLAG; + + /* LOST event: Abort any further processing */ + return (GSOCK_LOST_FLAG & flags); + } + + /* Check for readability */ + if (wxFD_ISSET(m_fd, &readfds)) + { + result |= GSOCK_INPUT_FLAG; + + if (m_server && m_stream) + { + /* This is a TCP server socket that detected a connection. + While the INPUT_FLAG is also set, it doesn't matter on + this kind of sockets, as we can only Accept() from them. */ + m_detected |= GSOCK_CONNECTION_FLAG; + } + } + + /* Check for writability */ + if (wxFD_ISSET(m_fd, &writefds)) + { + if (m_establishing && !m_server) + { + int error; + SOCKOPTLEN_T len = sizeof(error); + m_establishing = false; + getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len); + + if (error) + { + m_detected = GSOCK_LOST_FLAG; + + /* LOST event: Abort any further processing */ + return (GSOCK_LOST_FLAG & flags); + } + else + { + m_detected |= GSOCK_CONNECTION_FLAG; + } + } + else + { + result |= GSOCK_OUTPUT_FLAG; + } + } + + return (result | m_detected) & flags; } /* Flags */