- NOWAIT flag now implemented
- WaitForXXX are now correct (will not report readability / writability if in the middle of a defered read / write operation) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3688 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -3,8 +3,9 @@
|
|||||||
// Purpose: Socket handler classes
|
// Purpose: Socket handler classes
|
||||||
// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
|
// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
|
||||||
// Created: April 1997
|
// Created: April 1997
|
||||||
// Updated: July 1999
|
// Updated: September 1999
|
||||||
// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
|
// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
|
||||||
|
// (C) 1999, Guillermo Rodriguez Garcia
|
||||||
// RCS_ID: $Id$
|
// RCS_ID: $Id$
|
||||||
// License: see wxWindows license
|
// License: see wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -220,11 +221,25 @@ wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
|
|||||||
|
|
||||||
// If we have got the whole needed buffer, return immediately
|
// If we have got the whole needed buffer, return immediately
|
||||||
if (!nbytes)
|
if (!nbytes)
|
||||||
{
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
|
||||||
|
|
||||||
if (m_flags & SPEED & WAITALL) // SPEED && WAITALL
|
// Possible combinations (they are checked in this order)
|
||||||
|
// NOWAIT
|
||||||
|
// SPEED | WAITALL
|
||||||
|
// SPEED
|
||||||
|
// WAITALL
|
||||||
|
// NONE
|
||||||
|
//
|
||||||
|
if (m_flags & NOWAIT) // NOWAIT
|
||||||
|
{
|
||||||
|
GSocket_SetNonBlocking(m_socket, TRUE);
|
||||||
|
ret = GSocket_Read(m_socket, buffer, nbytes);
|
||||||
|
GSocket_SetNonBlocking(m_socket, FALSE);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
m_lcount += ret;
|
||||||
|
}
|
||||||
|
else if (m_flags & SPEED & WAITALL) // SPEED, WAITALL
|
||||||
{
|
{
|
||||||
while (ret > 0 && nbytes > 0)
|
while (ret > 0 && nbytes > 0)
|
||||||
{
|
{
|
||||||
@@ -237,14 +252,14 @@ wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
m_lcount ++;
|
m_lcount ++;
|
||||||
}
|
}
|
||||||
else if (m_flags & SPEED) // SPEED && !WAITALL
|
else if (m_flags & SPEED) // SPEED, !WAITALL
|
||||||
{
|
{
|
||||||
ret = GSocket_Read(m_socket, buffer, nbytes);
|
ret = GSocket_Read(m_socket, buffer, nbytes);
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
m_lcount += ret;
|
m_lcount += ret;
|
||||||
}
|
}
|
||||||
else // !SPEED
|
else // NONE or WAITALL
|
||||||
{
|
{
|
||||||
ret = DeferRead(buffer, nbytes);
|
ret = DeferRead(buffer, nbytes);
|
||||||
|
|
||||||
@@ -277,7 +292,7 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes)
|
|||||||
// compilers in which wxUint32 was actually a 16-bit unsigned integer
|
// compilers in which wxUint32 was actually a 16-bit unsigned integer
|
||||||
|
|
||||||
old_flags = m_flags;
|
old_flags = m_flags;
|
||||||
SetFlags(WAITALL | SPEED);
|
SetFlags(old_flags | WAITALL);
|
||||||
|
|
||||||
Read((char *)&msg, sizeof(msg));
|
Read((char *)&msg, sizeof(msg));
|
||||||
if (m_lcount != sizeof(msg))
|
if (m_lcount != sizeof(msg))
|
||||||
@@ -426,7 +441,23 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_flags & SPEED & WAITALL) // SPEED && WAITALL
|
// Possible combinations (they are checked in this order)
|
||||||
|
// NOWAIT
|
||||||
|
// SPEED | WAITALL
|
||||||
|
// SPEED
|
||||||
|
// WAITALL
|
||||||
|
// NONE
|
||||||
|
//
|
||||||
|
if (m_flags & NOWAIT) // NOWAIT
|
||||||
|
{
|
||||||
|
GSocket_SetNonBlocking(m_socket, TRUE);
|
||||||
|
ret = GSocket_Write(m_socket, buffer, nbytes);
|
||||||
|
GSocket_SetNonBlocking(m_socket, FALSE);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
m_lcount += ret;
|
||||||
|
}
|
||||||
|
else if (m_flags & SPEED & WAITALL) // SPEED, WAITALL
|
||||||
{
|
{
|
||||||
while (ret > 0 && nbytes > 0)
|
while (ret > 0 && nbytes > 0)
|
||||||
{
|
{
|
||||||
@@ -439,14 +470,14 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
m_lcount ++;
|
m_lcount ++;
|
||||||
}
|
}
|
||||||
else if (m_flags & SPEED) // SPEED && !WAITALL
|
else if (m_flags & SPEED) // SPEED, !WAITALL
|
||||||
{
|
{
|
||||||
ret = GSocket_Write(m_socket, buffer, nbytes);
|
ret = GSocket_Write(m_socket, buffer, nbytes);
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
m_lcount += ret;
|
m_lcount += ret;
|
||||||
}
|
}
|
||||||
else // !SPEED
|
else // NONE or WAITALL
|
||||||
{
|
{
|
||||||
ret = DeferWrite(buffer, nbytes);
|
ret = DeferWrite(buffer, nbytes);
|
||||||
|
|
||||||
@@ -486,9 +517,8 @@ wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes)
|
|||||||
msg.len[2] = (char) (nbytes >> 16) & 0xff;
|
msg.len[2] = (char) (nbytes >> 16) & 0xff;
|
||||||
msg.len[3] = (char) (nbytes >> 24) & 0xff;
|
msg.len[3] = (char) (nbytes >> 24) & 0xff;
|
||||||
|
|
||||||
// GRG: We need WAITALL | SPEED
|
|
||||||
old_flags = m_flags;
|
old_flags = m_flags;
|
||||||
SetFlags(WAITALL | SPEED);
|
SetFlags(old_flags | WAITALL);
|
||||||
|
|
||||||
if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
|
if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
|
||||||
{
|
{
|
||||||
@@ -699,7 +729,11 @@ bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags fla
|
|||||||
int state = -1;
|
int state = -1;
|
||||||
|
|
||||||
// Check for valid socket
|
// Check for valid socket
|
||||||
if ((!m_connected && !m_establishing) || !m_socket)
|
if (!m_socket)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// If it is not a server, it must be connected or establishing connection
|
||||||
|
if ((m_type != SOCK_SERVER) && (!m_connected && !m_establishing))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Check for valid timeout value
|
// Check for valid timeout value
|
||||||
@@ -714,17 +748,50 @@ bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags fla
|
|||||||
timer.Start(timeout, TRUE);
|
timer.Start(timeout, TRUE);
|
||||||
|
|
||||||
// Active polling (without using events)
|
// Active polling (without using events)
|
||||||
result = GSocket_Select(m_socket, flags);
|
//
|
||||||
|
// NOTE: this duplicates some of the code in OnRequest (lost
|
||||||
while ((result == 0) && (state == -1))
|
// connection and connection establishment handling) but this
|
||||||
|
// doesn't hurt. It has to be here because the event might
|
||||||
|
// be a bit delayed, and it has to be in OnRequest as well
|
||||||
|
// because maybe the WaitXXX functions are not being used.
|
||||||
|
//
|
||||||
|
while (state == -1)
|
||||||
{
|
{
|
||||||
|
result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG);
|
||||||
|
|
||||||
|
// Connection lost
|
||||||
|
if (result & GSOCK_LOST_FLAG)
|
||||||
|
{
|
||||||
|
timer.Stop();
|
||||||
|
m_defer_buffer = NULL;
|
||||||
|
Close();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Incoming connection (server) or connection established (client)
|
||||||
|
if (result & GSOCK_CONNECTION_FLAG)
|
||||||
|
{
|
||||||
|
timer.Stop();
|
||||||
|
m_connected = TRUE;
|
||||||
|
m_establishing = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are in the middle of a deferred R/W, ignore these.
|
||||||
|
if ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
|
||||||
|
{
|
||||||
|
if (m_defer_buffer == NULL)
|
||||||
|
{
|
||||||
|
timer.Stop();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wxYield();
|
wxYield();
|
||||||
result = GSocket_Select(m_socket, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.Stop();
|
timer.Stop();
|
||||||
|
return FALSE;
|
||||||
return (result != 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxSocketBase::Wait(long seconds, long milliseconds)
|
bool wxSocketBase::Wait(long seconds, long milliseconds)
|
||||||
@@ -737,12 +804,12 @@ bool wxSocketBase::Wait(long seconds, long milliseconds)
|
|||||||
|
|
||||||
bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
|
bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
|
||||||
{
|
{
|
||||||
return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
|
return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
|
bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
|
||||||
{
|
{
|
||||||
return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
|
return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
|
bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
|
||||||
@@ -830,6 +897,12 @@ void wxSocketBase::OnRequest(wxSocketNotify req_evt)
|
|||||||
wxSocketEvent event(m_id);
|
wxSocketEvent event(m_id);
|
||||||
wxSocketEventFlags flag = EventToNotify(req_evt);
|
wxSocketEventFlags flag = EventToNotify(req_evt);
|
||||||
|
|
||||||
|
// NOTE: this duplicates some of the code in _Wait (lost
|
||||||
|
// connection and connection establishment handling) but
|
||||||
|
// this doesn't hurt. It has to be here because maybe the
|
||||||
|
// WaitXXX are not being used, and it has to be in _Wait
|
||||||
|
// as well because the event might be a bit delayed.
|
||||||
|
//
|
||||||
switch(req_evt)
|
switch(req_evt)
|
||||||
{
|
{
|
||||||
case wxSOCKET_CONNECTION:
|
case wxSOCKET_CONNECTION:
|
||||||
@@ -1028,7 +1101,7 @@ wxSocketBase *wxSocketServer::Accept(bool wait)
|
|||||||
|
|
||||||
bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
|
bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
|
||||||
{
|
{
|
||||||
return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
|
return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
@@ -1102,33 +1175,15 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
|
|||||||
|
|
||||||
bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
|
bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
|
||||||
{
|
{
|
||||||
bool ret;
|
if (m_connected) // Already connected
|
||||||
|
|
||||||
if (m_connected) // Already connected
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (!m_establishing || !m_socket) // No connection in progress
|
if (!m_establishing || !m_socket) // No connection in progress
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
ret = _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
|
return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
|
||||||
|
|
||||||
// GRG: m_connected and m_establishing will be updated in
|
|
||||||
// OnRequest(), but we do it here anyway because sometimes
|
|
||||||
// the event might be a bit delayed, and if that happens,
|
|
||||||
// when WaitOnConnect() returns, m_connected will still be
|
|
||||||
// FALSE. We have to do it as well in OnRequest because
|
|
||||||
// maybe WaitOnConnect() is not being used...
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
m_connected = GSocket_Select(m_socket, GSOCK_CONNECTION_FLAG);
|
|
||||||
m_establishing = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_connected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
// wxSocketEvent
|
// wxSocketEvent
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user