From: Vadim Zeitlin Date: Sat, 27 Dec 2008 17:56:03 +0000 (+0000) Subject: got rid of wxSocketBase::m_error which could get out of sync with wxSocketImpl::m_err... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/64b1cea09aac1077469090dc2dac9a139a509833 got rid of wxSocketBase::m_error which could get out of sync with wxSocketImpl::m_error -- one error indicator is enough git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/socket.h b/include/wx/socket.h index f0736f4f05..2cb0467ce5 100644 --- a/include/wx/socket.h +++ b/include/wx/socket.h @@ -116,7 +116,7 @@ public: // state bool Ok() const { return IsOk(); } bool IsOk() const { return m_impl != NULL; } - bool Error() const { return m_error; } + bool Error() const { return LastError() != wxSOCKET_NOERROR; } bool IsClosed() const { return m_closed; } bool IsConnected() const { return m_connected; } bool IsData() { return WaitForRead(0, 0); } @@ -217,6 +217,9 @@ private: void Pushback(const void *buffer, wxUint32 size); wxUint32 GetPushback(void *buffer, wxUint32 size, bool peek); + // store the given error as the LastError() + void SetError(wxSocketError error); + private: // socket wxSocketImpl *m_impl; // port-specific implementation @@ -228,9 +231,7 @@ private: bool m_establishing; // establishing connection? bool m_reading; // busy reading? bool m_writing; // busy writing? - bool m_error; // did last IO call fail? bool m_closed; // was the other end closed? - // (notice that m_error is also set then) wxUint32 m_lcount; // last IO transaction size unsigned long m_timeout; // IO timeout value in seconds wxList m_states; // stack of states diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 222ca488ba..3ac0e18021 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -597,7 +597,6 @@ void wxSocketBase::Init() m_establishing = m_reading = m_writing = - m_error = m_closed = false; m_lcount = 0; m_timeout = 600; @@ -688,9 +687,14 @@ bool wxSocketBase::Destroy() } // ---------------------------------------------------------------------------- -// simply accessors +// simple accessors // ---------------------------------------------------------------------------- +void wxSocketBase::SetError(wxSocketError error) +{ + m_impl->m_error = error; +} + wxSocketError wxSocketBase::LastError() const { return m_impl->GetError(); @@ -700,7 +704,7 @@ wxSocketError wxSocketBase::LastError() const // Basic IO calls // -------------------------------------------------------------------------- -// The following IO operations update m_error and m_lcount: +// The following IO operations update m_lcount: // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard} bool wxSocketBase::Close() { @@ -722,12 +726,6 @@ wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes) m_lcount = DoRead(buffer, nbytes); - // If in wxSOCKET_WAITALL mode, all bytes should have been read. - if (m_flags & wxSOCKET_WAITALL) - m_error = (m_lcount != nbytes); - else - m_error = (m_lcount == 0); - // Allow read events from now on m_reading = false; @@ -758,10 +756,15 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes) if ( m_flags & wxSOCKET_NOWAIT ) { int ret = m_impl->Read(buffer, nbytes); - if ( ret < 0 ) - return 0; - - total += ret; + if ( ret == -1 ) + { + if ( m_impl->GetLastError() != wxSOCKET_WOULDBLOCK ) + SetError(wxSOCKET_IOERR); + } + else // not an error, even if we didn't read anything + { + total += ret; + } } else // blocking socket { @@ -782,10 +785,10 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes) break; } - if ( ret < 0 ) + if ( ret == -1 ) { - // this will be always interpreted as error by Read() - return 0; + SetError(wxSOCKET_IOERR); + break; } total += ret; @@ -803,6 +806,11 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes) buffer += ret; } + + // it's an error to not read everything in wxSOCKET_WAITALL mode or to + // not read anything otherwise + if ( ((m_flags & wxSOCKET_WAITALL) && nbytes) || !total ) + SetError(wxSOCKET_IOERR); } return total; @@ -810,9 +818,6 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes) wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes) { - wxUint32 len, len2, sig, total; - bool error; - int old_flags; struct { unsigned char sig[4]; @@ -822,86 +827,69 @@ wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes) // Mask read events m_reading = true; - total = 0; - error = true; - old_flags = m_flags; + int old_flags = m_flags; SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL); - if (DoRead(&msg, sizeof(msg)) != sizeof(msg)) - goto exit; - - sig = (wxUint32)msg.sig[0]; - sig |= (wxUint32)(msg.sig[1] << 8); - sig |= (wxUint32)(msg.sig[2] << 16); - sig |= (wxUint32)(msg.sig[3] << 24); - - if (sig != 0xfeeddead) + bool ok = false; + if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) ) { - wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); - goto exit; - } + wxUint32 sig = (wxUint32)msg.sig[0]; + sig |= (wxUint32)(msg.sig[1] << 8); + sig |= (wxUint32)(msg.sig[2] << 16); + sig |= (wxUint32)(msg.sig[3] << 24); - len = (wxUint32)msg.len[0]; - len |= (wxUint32)(msg.len[1] << 8); - len |= (wxUint32)(msg.len[2] << 16); - len |= (wxUint32)(msg.len[3] << 24); + if ( sig == 0xfeeddead ) + { + wxUint32 len = (wxUint32)msg.len[0]; + len |= (wxUint32)(msg.len[1] << 8); + len |= (wxUint32)(msg.len[2] << 16); + len |= (wxUint32)(msg.len[3] << 24); - if (len > nbytes) - { - len2 = len - nbytes; - len = nbytes; - } - else - len2 = 0; + wxUint32 len2; + if (len > nbytes) + { + len2 = len - nbytes; + len = nbytes; + } + else + len2 = 0; - // Don't attempt to read if the msg was zero bytes long. - if (len) - { - total = DoRead(buffer, len); + // Don't attempt to read if the msg was zero bytes long. + m_lcount = len ? DoRead(buffer, len) : 0; - if (total != len) - goto exit; - } + if ( len2 ) + { + char discard_buffer[MAX_DISCARD_SIZE]; + long discard_len; + + // NOTE: discarded bytes don't add to m_lcount. + do + { + discard_len = len2 > MAX_DISCARD_SIZE + ? MAX_DISCARD_SIZE + : len2; + discard_len = DoRead(discard_buffer, (wxUint32)discard_len); + len2 -= (wxUint32)discard_len; + } + while ((discard_len > 0) && len2); + } - if (len2) - { - char *discard_buffer = new char[MAX_DISCARD_SIZE]; - long discard_len; + if ( !len2 && DoRead(&msg, sizeof(msg)) == sizeof(msg) ) + { + sig = (wxUint32)msg.sig[0]; + sig |= (wxUint32)(msg.sig[1] << 8); + sig |= (wxUint32)(msg.sig[2] << 16); + sig |= (wxUint32)(msg.sig[3] << 24); - // NOTE: discarded bytes don't add to m_lcount. - do - { - discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2); - discard_len = DoRead(discard_buffer, (wxUint32)discard_len); - len2 -= (wxUint32)discard_len; + if ( sig == 0xdeadfeed ) + ok = true; + } } - while ((discard_len > 0) && len2); - - delete [] discard_buffer; - - if (len2 != 0) - goto exit; - } - if (DoRead(&msg, sizeof(msg)) != sizeof(msg)) - goto exit; - - sig = (wxUint32)msg.sig[0]; - sig |= (wxUint32)(msg.sig[1] << 8); - sig |= (wxUint32)(msg.sig[2] << 16); - sig |= (wxUint32)(msg.sig[3] << 24); - - if (sig != 0xdeadfeed) - { - wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); - goto exit; } - // everything was OK - error = false; + if ( !ok ) + SetError(wxSOCKET_IOERR); -exit: - m_error = error; - m_lcount = total; m_reading = false; SetFlags(old_flags); @@ -916,12 +904,6 @@ wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes) m_lcount = DoRead(buffer, nbytes); Pushback(buffer, m_lcount); - // If in wxSOCKET_WAITALL mode, all bytes should have been read. - if (m_flags & wxSOCKET_WAITALL) - m_error = (m_lcount != nbytes); - else - m_error = (m_lcount == 0); - // Allow read events again m_reading = false; @@ -935,12 +917,6 @@ wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes) m_lcount = DoWrite(buffer, nbytes); - // If in wxSOCKET_WAITALL mode, all bytes should have been written. - if (m_flags & wxSOCKET_WAITALL) - m_error = (m_lcount != nbytes); - else - m_error = (m_lcount == 0); - // Allow write events again m_writing = false; @@ -963,8 +939,15 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes) if ( m_flags & wxSOCKET_NOWAIT ) { const int ret = m_impl->Write(buffer, nbytes); - if ( ret > 0 ) + if ( ret == -1 ) + { + if ( m_impl->GetLastError() != wxSOCKET_WOULDBLOCK ) + SetError(wxSOCKET_IOERR); + } + else + { total += ret; + } } else // blocking socket { @@ -980,8 +963,11 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes) break; } - if ( ret < 0 ) - return 0; + if ( ret == -1 ) + { + SetError(wxSOCKET_IOERR); + break; + } total += ret; if ( !(m_flags & wxSOCKET_WAITALL) ) @@ -993,6 +979,9 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes) buffer += ret; } + + if ( ((m_flags & wxSOCKET_WAITALL) && nbytes) || !total ) + SetError(wxSOCKET_IOERR); } return total; @@ -1000,8 +989,6 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes) wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes) { - wxUint32 total; - bool error; struct { unsigned char sig[4]; @@ -1011,8 +998,7 @@ wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes) // Mask write events m_writing = true; - error = true; - total = 0; + const int old_flags = m_flags; SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL); msg.sig[0] = (unsigned char) 0xad; @@ -1025,33 +1011,31 @@ wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes) msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff); msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff); - if (DoWrite(&msg, sizeof(msg)) < sizeof(msg)) - goto exit; - - total = DoWrite(buffer, nbytes); - - if (total < nbytes) - goto exit; - - msg.sig[0] = (unsigned char) 0xed; - msg.sig[1] = (unsigned char) 0xfe; - msg.sig[2] = (unsigned char) 0xad; - msg.sig[3] = (unsigned char) 0xde; - msg.len[0] = - msg.len[1] = - msg.len[2] = - msg.len[3] = (char) 0; - - if ((DoWrite(&msg, sizeof(msg))) < sizeof(msg)) - goto exit; + bool ok = false; + if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) ) + { + m_lcount = DoWrite(buffer, nbytes); + if ( m_lcount == nbytes ) + { + msg.sig[0] = (unsigned char) 0xed; + msg.sig[1] = (unsigned char) 0xfe; + msg.sig[2] = (unsigned char) 0xad; + msg.sig[3] = (unsigned char) 0xde; + msg.len[0] = + msg.len[1] = + msg.len[2] = + msg.len[3] = (char) 0; + + if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg)) + ok = true; + } + } - // everything was OK - error = false; + if ( !ok ) + SetError(wxSOCKET_IOERR); -exit: - m_error = error; - m_lcount = total; m_writing = false; + SetFlags(old_flags); return *this; } @@ -1061,7 +1045,7 @@ wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes) if (nbytes != 0) Pushback(buffer, nbytes); - m_error = false; + SetError(wxSOCKET_NOERROR); m_lcount = nbytes; return *this; @@ -1076,6 +1060,7 @@ wxSocketBase& wxSocketBase::Discard() // Mask read events m_reading = true; + const int old_flags = m_flags; SetFlags(wxSOCKET_NOWAIT); do @@ -1087,11 +1072,13 @@ wxSocketBase& wxSocketBase::Discard() delete[] buffer; m_lcount = total; - m_error = false; + SetError(wxSOCKET_NOERROR); // Allow read events again m_reading = false; + SetFlags(old_flags); + return *this; } @@ -1632,7 +1619,7 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait) { wxFAIL_MSG( "can only be called for a valid server socket" ); - m_error = wxSOCKET_INVSOCK; + SetError(wxSOCKET_INVSOCK); return false; } @@ -1642,7 +1629,7 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait) // wait until we get a connection if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) ) { - m_error = wxSOCKET_TIMEDOUT; + SetError(wxSOCKET_TIMEDOUT); return false; } @@ -1652,7 +1639,7 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait) if ( !sock.m_impl ) { - m_error = m_impl->GetLastError(); + SetError(m_impl->GetLastError()); return false; } diff --git a/src/msw/sockmsw.cpp b/src/msw/sockmsw.cpp index d7773c0c8a..b5f1c91deb 100644 --- a/src/msw/sockmsw.cpp +++ b/src/msw/sockmsw.cpp @@ -448,7 +448,7 @@ void wxSocketImplMSW::DoClose() closesocket(m_fd); } -wxSocketError wxSocketImplUnix::GetLastError() const +wxSocketError wxSocketImplMSW::GetLastError() const { switch ( WSAGetLastError() ) {