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
This commit is contained in:
Vadim Zeitlin
2008-12-27 17:56:03 +00:00
parent 95fa881e92
commit 64b1cea09a
3 changed files with 129 additions and 141 deletions

View File

@@ -116,7 +116,7 @@ public:
// state // state
bool Ok() const { return IsOk(); } bool Ok() const { return IsOk(); }
bool IsOk() const { return m_impl != NULL; } 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 IsClosed() const { return m_closed; }
bool IsConnected() const { return m_connected; } bool IsConnected() const { return m_connected; }
bool IsData() { return WaitForRead(0, 0); } bool IsData() { return WaitForRead(0, 0); }
@@ -217,6 +217,9 @@ private:
void Pushback(const void *buffer, wxUint32 size); void Pushback(const void *buffer, wxUint32 size);
wxUint32 GetPushback(void *buffer, wxUint32 size, bool peek); wxUint32 GetPushback(void *buffer, wxUint32 size, bool peek);
// store the given error as the LastError()
void SetError(wxSocketError error);
private: private:
// socket // socket
wxSocketImpl *m_impl; // port-specific implementation wxSocketImpl *m_impl; // port-specific implementation
@@ -228,9 +231,7 @@ private:
bool m_establishing; // establishing connection? bool m_establishing; // establishing connection?
bool m_reading; // busy reading? bool m_reading; // busy reading?
bool m_writing; // busy writing? bool m_writing; // busy writing?
bool m_error; // did last IO call fail?
bool m_closed; // was the other end closed? bool m_closed; // was the other end closed?
// (notice that m_error is also set then)
wxUint32 m_lcount; // last IO transaction size wxUint32 m_lcount; // last IO transaction size
unsigned long m_timeout; // IO timeout value in seconds unsigned long m_timeout; // IO timeout value in seconds
wxList m_states; // stack of states wxList m_states; // stack of states

View File

@@ -597,7 +597,6 @@ void wxSocketBase::Init()
m_establishing = m_establishing =
m_reading = m_reading =
m_writing = m_writing =
m_error =
m_closed = false; m_closed = false;
m_lcount = 0; m_lcount = 0;
m_timeout = 600; 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 wxSocketError wxSocketBase::LastError() const
{ {
return m_impl->GetError(); return m_impl->GetError();
@@ -700,7 +704,7 @@ wxSocketError wxSocketBase::LastError() const
// Basic IO calls // 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} // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
bool wxSocketBase::Close() bool wxSocketBase::Close()
{ {
@@ -722,12 +726,6 @@ wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
m_lcount = DoRead(buffer, 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 // Allow read events from now on
m_reading = false; m_reading = false;
@@ -758,11 +756,16 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
if ( m_flags & wxSOCKET_NOWAIT ) if ( m_flags & wxSOCKET_NOWAIT )
{ {
int ret = m_impl->Read(buffer, nbytes); int ret = m_impl->Read(buffer, nbytes);
if ( ret < 0 ) if ( ret == -1 )
return 0; {
if ( m_impl->GetLastError() != wxSOCKET_WOULDBLOCK )
SetError(wxSOCKET_IOERR);
}
else // not an error, even if we didn't read anything
{
total += ret; total += ret;
} }
}
else // blocking socket else // blocking socket
{ {
for ( ;; ) for ( ;; )
@@ -782,10 +785,10 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
break; break;
} }
if ( ret < 0 ) if ( ret == -1 )
{ {
// this will be always interpreted as error by Read() SetError(wxSOCKET_IOERR);
return 0; break;
} }
total += ret; total += ret;
@@ -803,6 +806,11 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
buffer += ret; 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; return total;
@@ -810,9 +818,6 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes) wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
{ {
wxUint32 len, len2, sig, total;
bool error;
int old_flags;
struct struct
{ {
unsigned char sig[4]; unsigned char sig[4];
@@ -822,30 +827,25 @@ wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
// Mask read events // Mask read events
m_reading = true; m_reading = true;
total = 0; int old_flags = m_flags;
error = true;
old_flags = m_flags;
SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL); SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
if (DoRead(&msg, sizeof(msg)) != sizeof(msg)) bool ok = false;
goto exit; if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) )
{
sig = (wxUint32)msg.sig[0]; wxUint32 sig = (wxUint32)msg.sig[0];
sig |= (wxUint32)(msg.sig[1] << 8); sig |= (wxUint32)(msg.sig[1] << 8);
sig |= (wxUint32)(msg.sig[2] << 16); sig |= (wxUint32)(msg.sig[2] << 16);
sig |= (wxUint32)(msg.sig[3] << 24); sig |= (wxUint32)(msg.sig[3] << 24);
if (sig != 0xfeeddead) if ( sig == 0xfeeddead )
{ {
wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); wxUint32 len = (wxUint32)msg.len[0];
goto exit;
}
len = (wxUint32)msg.len[0];
len |= (wxUint32)(msg.len[1] << 8); len |= (wxUint32)(msg.len[1] << 8);
len |= (wxUint32)(msg.len[2] << 16); len |= (wxUint32)(msg.len[2] << 16);
len |= (wxUint32)(msg.len[3] << 24); len |= (wxUint32)(msg.len[3] << 24);
wxUint32 len2;
if (len > nbytes) if (len > nbytes)
{ {
len2 = len - nbytes; len2 = len - nbytes;
@@ -855,53 +855,41 @@ wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
len2 = 0; len2 = 0;
// Don't attempt to read if the msg was zero bytes long. // Don't attempt to read if the msg was zero bytes long.
if (len) m_lcount = len ? DoRead(buffer, len) : 0;
{
total = DoRead(buffer, len);
if (total != len) if ( len2 )
goto exit;
}
if (len2)
{ {
char *discard_buffer = new char[MAX_DISCARD_SIZE]; char discard_buffer[MAX_DISCARD_SIZE];
long discard_len; long discard_len;
// NOTE: discarded bytes don't add to m_lcount. // NOTE: discarded bytes don't add to m_lcount.
do do
{ {
discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2); discard_len = len2 > MAX_DISCARD_SIZE
? MAX_DISCARD_SIZE
: len2;
discard_len = DoRead(discard_buffer, (wxUint32)discard_len); discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
len2 -= (wxUint32)discard_len; len2 -= (wxUint32)discard_len;
} }
while ((discard_len > 0) && len2); while ((discard_len > 0) && len2);
delete [] discard_buffer;
if (len2 != 0)
goto exit;
} }
if (DoRead(&msg, sizeof(msg)) != sizeof(msg))
goto exit;
if ( !len2 && DoRead(&msg, sizeof(msg)) == sizeof(msg) )
{
sig = (wxUint32)msg.sig[0]; sig = (wxUint32)msg.sig[0];
sig |= (wxUint32)(msg.sig[1] << 8); sig |= (wxUint32)(msg.sig[1] << 8);
sig |= (wxUint32)(msg.sig[2] << 16); sig |= (wxUint32)(msg.sig[2] << 16);
sig |= (wxUint32)(msg.sig[3] << 24); sig |= (wxUint32)(msg.sig[3] << 24);
if (sig != 0xdeadfeed) if ( sig == 0xdeadfeed )
{ ok = true;
wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); }
goto exit; }
} }
// everything was OK if ( !ok )
error = false; SetError(wxSOCKET_IOERR);
exit:
m_error = error;
m_lcount = total;
m_reading = false; m_reading = false;
SetFlags(old_flags); SetFlags(old_flags);
@@ -916,12 +904,6 @@ wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
m_lcount = DoRead(buffer, nbytes); m_lcount = DoRead(buffer, nbytes);
Pushback(buffer, m_lcount); 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 // Allow read events again
m_reading = false; m_reading = false;
@@ -935,12 +917,6 @@ wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
m_lcount = DoWrite(buffer, 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 // Allow write events again
m_writing = false; m_writing = false;
@@ -963,9 +939,16 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
if ( m_flags & wxSOCKET_NOWAIT ) if ( m_flags & wxSOCKET_NOWAIT )
{ {
const int ret = m_impl->Write(buffer, nbytes); 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; total += ret;
} }
}
else // blocking socket else // blocking socket
{ {
for ( ;; ) for ( ;; )
@@ -980,8 +963,11 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
break; break;
} }
if ( ret < 0 ) if ( ret == -1 )
return 0; {
SetError(wxSOCKET_IOERR);
break;
}
total += ret; total += ret;
if ( !(m_flags & wxSOCKET_WAITALL) ) if ( !(m_flags & wxSOCKET_WAITALL) )
@@ -993,6 +979,9 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
buffer += ret; buffer += ret;
} }
if ( ((m_flags & wxSOCKET_WAITALL) && nbytes) || !total )
SetError(wxSOCKET_IOERR);
} }
return total; return total;
@@ -1000,8 +989,6 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes) wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
{ {
wxUint32 total;
bool error;
struct struct
{ {
unsigned char sig[4]; unsigned char sig[4];
@@ -1011,8 +998,7 @@ wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
// Mask write events // Mask write events
m_writing = true; m_writing = true;
error = true; const int old_flags = m_flags;
total = 0;
SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL); SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
msg.sig[0] = (unsigned char) 0xad; msg.sig[0] = (unsigned char) 0xad;
@@ -1025,14 +1011,12 @@ wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff); msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff); msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
if (DoWrite(&msg, sizeof(msg)) < sizeof(msg)) bool ok = false;
goto exit; if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) )
{
total = DoWrite(buffer, nbytes); m_lcount = DoWrite(buffer, nbytes);
if ( m_lcount == nbytes )
if (total < nbytes) {
goto exit;
msg.sig[0] = (unsigned char) 0xed; msg.sig[0] = (unsigned char) 0xed;
msg.sig[1] = (unsigned char) 0xfe; msg.sig[1] = (unsigned char) 0xfe;
msg.sig[2] = (unsigned char) 0xad; msg.sig[2] = (unsigned char) 0xad;
@@ -1042,16 +1026,16 @@ wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
msg.len[2] = msg.len[2] =
msg.len[3] = (char) 0; msg.len[3] = (char) 0;
if ((DoWrite(&msg, sizeof(msg))) < sizeof(msg)) if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg))
goto exit; ok = true;
}
}
// everything was OK if ( !ok )
error = false; SetError(wxSOCKET_IOERR);
exit:
m_error = error;
m_lcount = total;
m_writing = false; m_writing = false;
SetFlags(old_flags);
return *this; return *this;
} }
@@ -1061,7 +1045,7 @@ wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
if (nbytes != 0) if (nbytes != 0)
Pushback(buffer, nbytes); Pushback(buffer, nbytes);
m_error = false; SetError(wxSOCKET_NOERROR);
m_lcount = nbytes; m_lcount = nbytes;
return *this; return *this;
@@ -1076,6 +1060,7 @@ wxSocketBase& wxSocketBase::Discard()
// Mask read events // Mask read events
m_reading = true; m_reading = true;
const int old_flags = m_flags;
SetFlags(wxSOCKET_NOWAIT); SetFlags(wxSOCKET_NOWAIT);
do do
@@ -1087,11 +1072,13 @@ wxSocketBase& wxSocketBase::Discard()
delete[] buffer; delete[] buffer;
m_lcount = total; m_lcount = total;
m_error = false; SetError(wxSOCKET_NOERROR);
// Allow read events again // Allow read events again
m_reading = false; m_reading = false;
SetFlags(old_flags);
return *this; return *this;
} }
@@ -1632,7 +1619,7 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
{ {
wxFAIL_MSG( "can only be called for a valid server socket" ); wxFAIL_MSG( "can only be called for a valid server socket" );
m_error = wxSOCKET_INVSOCK; SetError(wxSOCKET_INVSOCK);
return false; return false;
} }
@@ -1642,7 +1629,7 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
// wait until we get a connection // wait until we get a connection
if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) ) if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) )
{ {
m_error = wxSOCKET_TIMEDOUT; SetError(wxSOCKET_TIMEDOUT);
return false; return false;
} }
@@ -1652,7 +1639,7 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
if ( !sock.m_impl ) if ( !sock.m_impl )
{ {
m_error = m_impl->GetLastError(); SetError(m_impl->GetLastError());
return false; return false;
} }

View File

@@ -448,7 +448,7 @@ void wxSocketImplMSW::DoClose()
closesocket(m_fd); closesocket(m_fd);
} }
wxSocketError wxSocketImplUnix::GetLastError() const wxSocketError wxSocketImplMSW::GetLastError() const
{ {
switch ( WSAGetLastError() ) switch ( WSAGetLastError() )
{ {