- 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:
Guillermo Rodriguez Garcia 1999-09-17 01:51:06 +00:00
parent 236ef8a966
commit af2fd9613a

View File

@ -3,8 +3,9 @@
// Purpose: Socket handler classes
// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
// Created: April 1997
// Updated: July 1999
// Updated: September 1999
// Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
// (C) 1999, Guillermo Rodriguez Garcia
// RCS_ID: $Id$
// License: see wxWindows license
/////////////////////////////////////////////////////////////////////////////
@ -184,7 +185,7 @@ int wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes)
if (GSocket_Select(m_socket, GSOCK_INPUT_FLAG))
DoDefer();
// Wait for buffer completion.
// Wait for buffer completion.
while (m_defer_buffer != NULL)
wxYield();
@ -220,11 +221,25 @@ wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
// If we have got the whole needed buffer, return immediately
if (!nbytes)
{
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)
{
@ -237,14 +252,14 @@ wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
if (ret < 0)
m_lcount ++;
}
else if (m_flags & SPEED) // SPEED && !WAITALL
else if (m_flags & SPEED) // SPEED, !WAITALL
{
ret = GSocket_Read(m_socket, buffer, nbytes);
if (ret > 0)
m_lcount += ret;
}
else // !SPEED
else // NONE or WAITALL
{
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
old_flags = m_flags;
SetFlags(WAITALL | SPEED);
SetFlags(old_flags | WAITALL);
Read((char *)&msg, sizeof(msg));
if (m_lcount != sizeof(msg))
@ -313,7 +328,7 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes)
else
len2 = 0;
// The "len &&" in the following statements is necessary so
// The "len &&" in the following statements is necessary so
// that we don't attempt to read (and possibly hang the system)
// if the message was zero bytes long
if (len && Read(buffer, len).LastCount() != len)
@ -400,7 +415,7 @@ int wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes)
if (GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))
DoDefer();
// Wait for buffer completion.
// Wait for buffer completion.
while (m_defer_buffer != NULL)
wxYield();
@ -426,7 +441,23 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
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)
{
@ -439,14 +470,14 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
if (ret < 0)
m_lcount ++;
}
else if (m_flags & SPEED) // SPEED && !WAITALL
else if (m_flags & SPEED) // SPEED, !WAITALL
{
ret = GSocket_Write(m_socket, buffer, nbytes);
if (ret > 0)
m_lcount += ret;
}
else // !SPEED
else // NONE or WAITALL
{
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[3] = (char) (nbytes >> 24) & 0xff;
// GRG: We need WAITALL | SPEED
old_flags = m_flags;
SetFlags(WAITALL | SPEED);
SetFlags(old_flags | WAITALL);
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;
// 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;
// Check for valid timeout value
@ -714,17 +748,50 @@ bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags fla
timer.Start(timeout, TRUE);
// Active polling (without using events)
result = GSocket_Select(m_socket, flags);
while ((result == 0) && (state == -1))
//
// NOTE: this duplicates some of the code in OnRequest (lost
// 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();
result = GSocket_Select(m_socket, flags);
}
timer.Stop();
return (result != 0);
return FALSE;
}
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)
{
return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG);
}
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)
@ -766,7 +833,7 @@ void wxSocketBase::SetFlags(wxSockFlags _flags)
{
m_flags = _flags;
}
wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
{
return m_flags;
@ -830,6 +897,12 @@ void wxSocketBase::OnRequest(wxSocketNotify req_evt)
wxSocketEvent event(m_id);
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)
{
case wxSOCKET_CONNECTION:
@ -1028,7 +1101,7 @@ wxSocketBase *wxSocketServer::Accept(bool wait)
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 ret;
if (m_connected) // Already connected
if (m_connected) // Already connected
return TRUE;
if (!m_establishing || !m_socket) // No connection in progress
if (!m_establishing || !m_socket) // No connection in progress
return FALSE;
ret = _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG | GSOCK_LOST_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;
return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
}
// --------------------------------------------------------------
// wxSocketEvent
// --------------------------------------------------------------