Add per-direction wxSocket wait flags and byte counters.

Allow to specify whether the socket should block until all the data is read or
written or, on the contrary, avoid blocking only when reading or writing
instead of always using the same behaviour in both directions.

Also add separate counters for the bytes read/written instead of using the
same one for both.

These changes make it possible to use the same socket for reading/writing in
different threads.

Closes #14506.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72591 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2012-09-30 22:21:44 +00:00
parent be4162218d
commit 294a09aa8c
5 changed files with 150 additions and 26 deletions

View File

@@ -817,6 +817,8 @@ void wxSocketBase::Init()
m_writing =
m_closed = false;
m_lcount = 0;
m_lcount_read = 0;
m_lcount_write = 0;
m_timeout = 600;
m_beingDeleted = false;
@@ -947,7 +949,8 @@ wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
{
wxSocketReadGuard read(this);
m_lcount = DoRead(buffer, nbytes);
m_lcount_read = DoRead(buffer, nbytes);
m_lcount = m_lcount_read;
return *this;
}
@@ -983,7 +986,7 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
{
// if we don't want to wait, just return immediately
if ( m_flags & wxSOCKET_NOWAIT )
if ( m_flags & (wxSOCKET_NOWAIT|wxSOCKET_NOWAIT_READ ))
{
// this shouldn't be counted as an error in this case
SetError(wxSOCKET_NOERROR);
@@ -1019,7 +1022,7 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
// we're not going to read anything else and so if we haven't read
// anything (or not everything in wxSOCKET_WAITALL case) already,
// signal an error
if ( (m_flags & wxSOCKET_WAITALL) || !total )
if ( (m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ)) || !total )
SetError(wxSOCKET_IOERR);
break;
}
@@ -1028,7 +1031,7 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
// if we are happy to read something and not the entire nbytes bytes,
// then we're done
if ( !(m_flags & wxSOCKET_WAITALL) )
if ( !(m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ)) )
break;
nbytes -= ret;
@@ -1048,7 +1051,7 @@ wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
wxSocketReadGuard read(this);
wxSocketWaitModeChanger changeFlags(this, wxSOCKET_WAITALL);
wxSocketWaitModeChanger changeFlags(this, (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ));
bool ok = false;
if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) )
@@ -1075,7 +1078,8 @@ wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
len2 = 0;
// Don't attempt to read if the msg was zero bytes long.
m_lcount = len ? DoRead(buffer, len) : 0;
m_lcount_read = len ? DoRead(buffer, len) : 0;
m_lcount = m_lcount_read;
if ( len2 )
{
@@ -1131,7 +1135,8 @@ wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
{
wxSocketWriteGuard write(this);
m_lcount = DoWrite(buffer, nbytes);
m_lcount_write = DoWrite(buffer, nbytes);
m_lcount = m_lcount_write;
return *this;
}
@@ -1151,7 +1156,7 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
{
if ( m_impl->m_stream && !m_connected )
{
if ( (m_flags & wxSOCKET_WAITALL) || !total )
if ( (m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE)) || !total )
SetError(wxSOCKET_IOERR);
break;
}
@@ -1161,7 +1166,7 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
{
if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
{
if ( m_flags & wxSOCKET_NOWAIT )
if ( m_flags & (wxSOCKET_NOWAIT|wxSOCKET_NOWAIT_WRITE) )
break;
if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG) )
@@ -1181,7 +1186,7 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
total += ret;
if ( !(m_flags & wxSOCKET_WAITALL) )
if ( !(m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE)) )
break;
nbytes -= ret;
@@ -1201,7 +1206,7 @@ wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
wxSocketWriteGuard write(this);
wxSocketWaitModeChanger changeFlags(this, wxSOCKET_WAITALL);
wxSocketWaitModeChanger changeFlags(this, (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE));
msg.sig[0] = (unsigned char) 0xad;
msg.sig[1] = (unsigned char) 0xde;
@@ -1216,8 +1221,9 @@ wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
bool ok = false;
if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) )
{
m_lcount = DoWrite(buffer, nbytes);
if ( m_lcount == nbytes )
m_lcount_write = DoWrite(buffer, nbytes);
m_lcount = m_lcount_write;
if ( m_lcount_write == nbytes )
{
msg.sig[0] = (unsigned char) 0xed;
msg.sig[1] = (unsigned char) 0xfe;