Important changes to avoid dependence on events inside wxSocket

implementation (should also ease a console only version soon)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5322 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guillermo Rodriguez Garcia
2000-01-10 03:54:37 +00:00
parent 470d5a6769
commit 81b92e17cd
2 changed files with 141 additions and 290 deletions

View File

@@ -84,6 +84,7 @@ enum wxSockType
{ {
SOCK_CLIENT, SOCK_CLIENT,
SOCK_SERVER, SOCK_SERVER,
/* SOCK_DGRAM, */
SOCK_INTERNAL, SOCK_INTERNAL,
SOCK_UNINIT SOCK_UNINIT
}; };
@@ -112,49 +113,34 @@ public:
typedef void (*wxSockCbk)(wxSocketBase& sock, wxSocketNotify evt, char *cdata); typedef void (*wxSockCbk)(wxSocketBase& sock, wxSocketNotify evt, char *cdata);
protected: protected:
GSocket *m_socket; // GSocket GSocket *m_socket; // GSocket
int m_id; // Socket id (for event handler) int m_id; // Socket id (for event handler)
// Attributes // Attributes
wxSockFlags m_flags; // wxSocket flags wxSockFlags m_flags; // wxSocket flags
wxSockType m_type; // wxSocket type wxSockType m_type; // wxSocket type
wxSocketEventFlags m_neededreq; // Event mask wxSocketEventFlags m_neededreq; // Event mask
bool m_notify_state; // Notify events to users? bool m_notify_state; // Notify events to users?
bool m_connected; // Connected ?
bool m_establishing; // Establishing connection ?
bool m_reading; // Busy reading?
bool m_writing; // Busy writing?
bool m_error; // Did last IO call fail ?
wxUint32 m_lcount; // Last IO transaction size
unsigned long m_timeout; // IO timeout value
wxList m_states; // Stack of states
char *m_unread; // Pushback buffer // State
wxUint32 m_unrd_size; // Pushback buffer size bool m_connected; // Connected?
wxUint32 m_unrd_cur; // Pushback pointer (index into buffer) bool m_establishing; // Establishing connection?
bool m_reading; // Busy reading?
bool m_writing; // Busy writing?
bool m_error; // Did last IO call fail?
wxUint32 m_lcount; // Last IO transaction size
unsigned long m_timeout; // IO timeout value
wxList m_states; // Stack of states
bool m_interrupt; // Interrupt ongoing wait operations
// Async IO variables // Pushback buffer
enum char *m_unread; // Pushback buffer
{ wxUint32 m_unrd_size; // Pushback buffer size
NO_DEFER = 0, wxUint32 m_unrd_cur; // Pushback pointer (index into buffer)
DEFER_READ = 1,
DEFER_WRITE = 2
} m_defering; // Defering state
char *m_defer_buffer; // Defering target buffer
wxUint32 m_defer_nbytes; // Defering buffer size
wxTimer *m_defer_timer; // Timer for defering mode
/* // Callback
char *m_read_buffer; // Target buffer (read) wxSockCbk m_cbk; // C callback
char *m_write_buffer; // Target buffer (write) char *m_cdata; // C callback data
wxUint32 m_read_nbytes; // Buffer size (read)
wxUint32 m_write_nbytes; // Buffer size (write)
wxTimer *m_read_timer; // Timer (read)
wxTimer *m_write_timer; // Timer (write)
*/
wxSockCbk m_cbk; // C callback
char *m_cdata; // C callback data
public: public:
wxSocketBase(); wxSocketBase();
@@ -181,7 +167,7 @@ public:
inline wxSocketError LastError() const { return (wxSocketError)GSocket_GetError(m_socket); } inline wxSocketError LastError() const { return (wxSocketError)GSocket_GetError(m_socket); }
inline wxSockType GetType() const { return m_type; } inline wxSockType GetType() const { return m_type; }
// Some info on the socket... // Addresses
virtual bool GetPeer(wxSockAddress& addr_man) const; virtual bool GetPeer(wxSockAddress& addr_man) const;
virtual bool GetLocal(wxSockAddress& addr_man) const; virtual bool GetLocal(wxSockAddress& addr_man) const;
@@ -190,15 +176,23 @@ public:
void SetFlags(wxSockFlags flags); void SetFlags(wxSockFlags flags);
inline wxSockFlags GetFlags() const { return m_flags; }; inline wxSockFlags GetFlags() const { return m_flags; };
// Wait functions /* Wait functions
// seconds = -1 means default timeout (change with SetTimeout) * seconds = -1 means default timeout (change with SetTimeout)
// seconds, milliseconds = 0 means no wait * seconds, milliseconds = 0 means no wait
// seconds, milliseconds > 0 means specified wait * seconds, milliseconds > 0 means specified wait
*/
bool Wait(long seconds = -1, long milliseconds = 0); bool Wait(long seconds = -1, long milliseconds = 0);
bool WaitForRead(long seconds = -1, long milliseconds = 0); bool WaitForRead(long seconds = -1, long milliseconds = 0);
bool WaitForWrite(long seconds = -1, long milliseconds = 0); bool WaitForWrite(long seconds = -1, long milliseconds = 0);
bool WaitForLost(long seconds = -1, long milliseconds = 0); bool WaitForLost(long seconds = -1, long milliseconds = 0);
/* This function interrupts all ongoing wait operations for this
* socket; use it only as an escape mechanism (for example to close
* an app or to abort an operation). Reception of LOST events and
* calls to Close() automatically call this.
*/
void InterruptAllWaits() { m_interrupt = TRUE; };
// Save the current state of Socket // Save the current state of Socket
void SaveState(); void SaveState();
void RestoreState(); void RestoreState();
@@ -242,10 +236,6 @@ protected:
wxUint32 _Write(const char *buffer, wxUint32 nbytes); wxUint32 _Write(const char *buffer, wxUint32 nbytes);
bool _Wait(long seconds, long milliseconds, wxSocketEventFlags flags); bool _Wait(long seconds, long milliseconds, wxSocketEventFlags flags);
wxUint32 DeferRead(char *buffer, wxUint32 nbytes);
wxUint32 DeferWrite(const char *buffer, wxUint32 nbytes);
void DoDefer();
// Pushbacks // Pushbacks
void Pushback(const char *buffer, wxUint32 size); void Pushback(const char *buffer, wxUint32 size);
wxUint32 GetPushback(char *buffer, wxUint32 size, bool peek); wxUint32 GetPushback(char *buffer, wxUint32 size, bool peek);
@@ -259,7 +249,7 @@ class WXDLLEXPORT wxSocketServer : public wxSocketBase
public: public:
// 'service' can be a name or a port-number // 'service' can be a name or a port-number
wxSocketServer(wxSockAddress& addr_man, wxSockFlags flags = wxSocketBase::NONE); wxSocketServer(wxSockAddress& addr_man, wxSockFlags flags = wxSOCKET_NONE);
wxSocketBase* Accept(bool wait = TRUE); wxSocketBase* Accept(bool wait = TRUE);
bool AcceptWith(wxSocketBase& sock, bool wait = TRUE); bool AcceptWith(wxSocketBase& sock, bool wait = TRUE);
@@ -274,7 +264,7 @@ class WXDLLEXPORT wxSocketClient : public wxSocketBase
DECLARE_CLASS(wxSocketClient) DECLARE_CLASS(wxSocketClient)
public: public:
wxSocketClient(wxSockFlags flags = wxSocketBase::NONE); wxSocketClient(wxSockFlags flags = wxSOCKET_NONE);
virtual ~wxSocketClient(); virtual ~wxSocketClient();
virtual bool Connect(wxSockAddress& addr_man, bool wait = TRUE); virtual bool Connect(wxSockAddress& addr_man, bool wait = TRUE);

View File

@@ -26,6 +26,7 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// wxWindows headers // wxWindows headers
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#include "wx/defs.h" #include "wx/defs.h"
#include "wx/object.h" #include "wx/object.h"
#include "wx/string.h" #include "wx/string.h"
@@ -42,21 +43,18 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// wxSocket headers // wxSocket headers
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#include "wx/sckaddr.h" #include "wx/sckaddr.h"
#include "wx/socket.h" #include "wx/socket.h"
#if defined(__WXMSW__) || defined(__WXPM__) || defined(__WXMOTIF__) || defined(__WXMAC__) #define PROCESS_EVENTS() wxYield()
#define PROCESS_EVENTS() wxYield()
#elif defined(__WXGTK__)
#include <gtk/gtk.h>
#define PROCESS_EVENTS() gtk_main_iteration()
#endif
// -------------------------------------------------------------- // --------------------------------------------------------------
// ClassInfos // ClassInfos
// -------------------------------------------------------------- // --------------------------------------------------------------
IMPLEMENT_CLASS(wxSocketBase, wxObject) IMPLEMENT_CLASS(wxSocketBase, wxObject)
IMPLEMENT_CLASS(wxSocketServer, wxSocketBase) IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
IMPLEMENT_CLASS(wxSocketClient, wxSocketBase) IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
@@ -65,11 +63,11 @@ IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
class wxSocketState : public wxObject class wxSocketState : public wxObject
{ {
public: public:
bool notify_state; bool m_notify_state;
GSocketEventFlags evt_notify_state; GSocketEventFlags m_neededreq;
wxSockFlags socket_flags; wxSockFlags m_flags;
wxSocketBase::wxSockCbk c_callback; wxSocketBase::wxSockCbk m_cbk;
char *c_callback_data; char *m_cdata;
public: public:
wxSocketState() : wxObject() {} wxSocketState() : wxObject() {}
@@ -88,7 +86,6 @@ wxSocketBase::wxSocketBase(wxSockFlags _flags, wxSockType _type) :
m_reading(FALSE), m_writing(FALSE), m_reading(FALSE), m_writing(FALSE),
m_error(FALSE), m_lcount(0), m_timeout(600), m_states(), m_error(FALSE), m_lcount(0), m_timeout(600), m_states(),
m_unread(NULL), m_unrd_size(0), m_unrd_cur(0), m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
m_defering(NO_DEFER), m_defer_buffer(NULL), m_defer_timer(NULL),
m_cbk(NULL), m_cdata(NULL) m_cbk(NULL), m_cdata(NULL)
{ {
} }
@@ -102,7 +99,6 @@ wxSocketBase::wxSocketBase() :
m_reading(FALSE), m_writing(FALSE), m_reading(FALSE), m_writing(FALSE),
m_error(FALSE), m_lcount(0), m_timeout(600), m_states(), m_error(FALSE), m_lcount(0), m_timeout(600), m_states(),
m_unread(NULL), m_unrd_size(0), m_unrd_cur(0), m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
m_defering(NO_DEFER), m_defer_buffer(NULL), m_defer_timer(NULL),
m_cbk(NULL), m_cdata(NULL) m_cbk(NULL), m_cdata(NULL)
{ {
} }
@@ -122,6 +118,9 @@ wxSocketBase::~wxSocketBase()
bool wxSocketBase::Close() bool wxSocketBase::Close()
{ {
// Interrupt pending waits
InterruptAllWaits();
if (m_socket) if (m_socket)
{ {
// Disable callbacks // Disable callbacks
@@ -158,49 +157,6 @@ public:
} }
}; };
wxUint32 wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes)
{
// Timer for timeout
_wxSocketInternalTimer timer;
//wxLogMessage("Entrando a DeferRead, nbytes = %d", nbytes);
wxASSERT(m_defering == NO_DEFER);
// Set the defering mode to READ.
m_defering = DEFER_READ;
// Set the current buffer.
m_defer_buffer = buffer;
m_defer_nbytes = nbytes;
m_defer_timer = &timer;
timer.m_state = (int *)&m_defer_buffer;
timer.m_new_val = 0;
timer.Start((int)(m_timeout * 1000), FALSE);
// If the socket is readable, call DoDefer for the first time
if (GSocket_Select(m_socket, GSOCK_INPUT_FLAG))
{
//wxLogMessage("Llamando al primer DoDefer");
DoDefer();
}
// Wait for buffer completion.
while (m_defer_buffer != NULL)
PROCESS_EVENTS();
timer.Stop();
// Disable defering mode.
m_defering = NO_DEFER;
m_defer_timer = NULL;
// Return the number of bytes read from the socket.
//wxLogMessage("Saliendo de DeferRead: total: %d bytes", nbytes - m_defer_nbytes);
return nbytes-m_defer_nbytes;
}
wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes) wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
{ {
// Mask read events // Mask read events
@@ -237,13 +193,13 @@ wxUint32 wxSocketBase::_Read(char* buffer, wxUint32 nbytes)
return total; return total;
// Possible combinations (they are checked in this order) // Possible combinations (they are checked in this order)
// NOWAIT // wxSOCKET_NOWAIT
// SPEED | WAITALL // wxSOCKET_WAITALL | wxSOCKET_BLOCK
// SPEED // wxSOCKET_WAITALL
// WAITALL // wxSOCKET_BLOCK
// NONE // wxSOCKET_NONE
// //
if (m_flags & NOWAIT) // NOWAIT if (m_flags & wxSOCKET_NOWAIT)
{ {
GSocket_SetNonBlocking(m_socket, TRUE); GSocket_SetNonBlocking(m_socket, TRUE);
ret = GSocket_Read(m_socket, buffer, nbytes); ret = GSocket_Read(m_socket, buffer, nbytes);
@@ -252,32 +208,32 @@ wxUint32 wxSocketBase::_Read(char* buffer, wxUint32 nbytes)
if (ret > 0) if (ret > 0)
total += ret; total += ret;
} }
else if ((m_flags & SPEED) && (m_flags & WAITALL)) // SPEED, WAITALL else if (m_flags & wxSOCKET_WAITALL) // wxSOCKET_WAITALL
{ {
while (ret > 0 && nbytes > 0) while (ret > 0 && nbytes > 0)
{ {
if (!(m_flags & wxSOCKET_BLOCK) && !(WaitForRead()))
break;
ret = GSocket_Read(m_socket, buffer, nbytes); ret = GSocket_Read(m_socket, buffer, nbytes);
total += ret;
buffer += ret; if (ret > 0)
nbytes -= ret; {
total += ret;
buffer += ret;
nbytes -= ret;
}
} }
// In case the last call was an error ...
if (ret < 0)
total++;
} }
else if (m_flags & SPEED) // SPEED, !WAITALL else
{ {
ret = GSocket_Read(m_socket, buffer, nbytes); if ((m_flags & wxSOCKET_BLOCK) || WaitForRead())
{
ret = GSocket_Read(m_socket, buffer, nbytes);
if (ret > 0) if (ret > 0)
total += ret; total += ret;
} }
else // NONE or WAITALL
{
ret = DeferRead(buffer, nbytes);
if (ret > 0)
total += ret;
} }
return total; return total;
@@ -302,7 +258,7 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes)
total = 0; total = 0;
error = TRUE; error = TRUE;
old_flags = m_flags; old_flags = m_flags;
SetFlags((m_flags & SPEED) | WAITALL); SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
if (_Read((char *)&msg, sizeof(msg)) != sizeof(msg)) if (_Read((char *)&msg, sizeof(msg)) != sizeof(msg))
goto exit; goto exit;
@@ -399,8 +355,8 @@ wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes)
m_lcount = _Read(buffer, nbytes); m_lcount = _Read(buffer, nbytes);
Pushback(buffer, nbytes); Pushback(buffer, nbytes);
// If in WAITALL mode, all bytes should have been read. // If in wxSOCKET_WAITALL mode, all bytes should have been read.
if (m_flags & WAITALL) if (m_flags & wxSOCKET_WAITALL)
m_error = (m_lcount != nbytes); m_error = (m_lcount != nbytes);
else else
m_error = (m_lcount == 0); m_error = (m_lcount == 0);
@@ -412,51 +368,6 @@ wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes)
return *this; return *this;
} }
wxUint32 wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes)
{
// Timer for timeout
_wxSocketInternalTimer timer;
wxASSERT(m_defering == NO_DEFER);
//wxLogMessage("Entrando a DeferWrite");
m_defering = DEFER_WRITE;
// Set the current buffer
m_defer_buffer = (char *)buffer;
m_defer_nbytes = nbytes;
m_defer_timer = &timer;
// Start timer
timer.m_state = (int *)&m_defer_buffer;
timer.m_new_val = 0;
timer.Start((int)(m_timeout * 1000), FALSE);
// If the socket is writable, call DoDefer for the first time
if (GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))
{
//wxLogMessage("Llamando al primer DoDefer");
DoDefer();
}
// Wait for buffer completion.
while (m_defer_buffer != NULL)
PROCESS_EVENTS();
timer.Stop();
// Disable defering mode
m_defer_timer = NULL;
m_defering = NO_DEFER;
//wxString s;
//s.Printf(wxT("Saliendo de DeferWrite: total %d bytes"), nbytes-m_defer_nbytes);
//wxLogMessage(s);
return nbytes-m_defer_nbytes;
}
wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes) wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
{ {
// Mask write events // Mask write events
@@ -464,8 +375,8 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
m_lcount = _Write(buffer, nbytes); m_lcount = _Write(buffer, nbytes);
// If in WAITALL mode, all bytes should have been written. // If in wxSOCKET_WAITALL mode, all bytes should have been written.
if (m_flags & WAITALL) if (m_flags & wxSOCKET_WAITALL)
m_error = (m_lcount != nbytes); m_error = (m_lcount != nbytes);
else else
m_error = (m_lcount == 0); m_error = (m_lcount == 0);
@@ -486,13 +397,13 @@ wxUint32 wxSocketBase::_Write(const char *buffer, wxUint32 nbytes)
return 0; return 0;
// Possible combinations (they are checked in this order) // Possible combinations (they are checked in this order)
// NOWAIT // wxSOCKET_NOWAIT
// SPEED | WAITALL // wxSOCKET_WAITALL | wxSOCKET_BLOCK
// SPEED // wxSOCKET_WAITALL
// WAITALL // wxSOCKET_BLOCK
// NONE // wxSOCKET_NONE
// //
if (m_flags & NOWAIT) // NOWAIT if (m_flags & wxSOCKET_NOWAIT)
{ {
GSocket_SetNonBlocking(m_socket, TRUE); GSocket_SetNonBlocking(m_socket, TRUE);
ret = GSocket_Write(m_socket, buffer, nbytes); ret = GSocket_Write(m_socket, buffer, nbytes);
@@ -501,32 +412,32 @@ wxUint32 wxSocketBase::_Write(const char *buffer, wxUint32 nbytes)
if (ret > 0) if (ret > 0)
total = ret; total = ret;
} }
else if ((m_flags & SPEED) && (m_flags & WAITALL)) // SPEED, WAITALL else if (m_flags & wxSOCKET_WAITALL)
{ {
while (ret > 0 && nbytes > 0) while (ret > 0 && nbytes > 0)
{ {
if (!(m_flags & wxSOCKET_BLOCK) && !(WaitForWrite()))
break;
ret = GSocket_Write(m_socket, buffer, nbytes); ret = GSocket_Write(m_socket, buffer, nbytes);
total += ret;
buffer += ret; if (ret > 0)
nbytes -= ret; {
total += ret;
buffer += ret;
nbytes -= ret;
}
} }
// In case the last call was an error ...
if (ret < 0)
total ++;
} }
else if (m_flags & SPEED) // SPEED, !WAITALL else
{ {
ret = GSocket_Write(m_socket, buffer, nbytes); if ((m_flags & wxSOCKET_BLOCK) || WaitForWrite())
{
ret = GSocket_Write(m_socket, buffer, nbytes);
if (ret > 0) if (ret > 0)
total = ret; total = ret;
} }
else // NONE or WAITALL
{
ret = DeferWrite(buffer, nbytes);
if (ret > 0)
total = ret;
} }
return total; return total;
@@ -548,7 +459,7 @@ wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes)
error = TRUE; error = TRUE;
total = 0; total = 0;
old_flags = m_flags; old_flags = m_flags;
SetFlags((m_flags & SPEED) | WAITALL); SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
// warning about 'cast truncates constant value' // warning about 'cast truncates constant value'
#ifdef __VISUALC__ #ifdef __VISUALC__
@@ -617,43 +528,6 @@ wxSocketBase& wxSocketBase::Unread(const char *buffer, wxUint32 nbytes)
return *this; return *this;
} }
void wxSocketBase::DoDefer()
{
int ret;
if (!m_defer_buffer)
return;
switch(m_defering)
{
case DEFER_READ:
ret = GSocket_Read(m_socket, m_defer_buffer, m_defer_nbytes);
break;
case DEFER_WRITE:
ret = GSocket_Write(m_socket, m_defer_buffer, m_defer_nbytes);
break;
default:
ret = -1;
}
if (ret >= 0)
m_defer_nbytes -= ret;
// If we are waiting for all bytes to be acquired, keep the defering
// mode enabled.
if (!(m_flags & WAITALL) || !m_defer_nbytes || ret < 0)
{
m_defer_buffer = NULL;
}
else
{
m_defer_buffer += ret;
m_defer_timer->Start((int)(m_timeout * 1000), FALSE);
}
//wxLogMessage("DoDefer ha transferido %d bytes", ret);
}
wxSocketBase& wxSocketBase::Discard() wxSocketBase& wxSocketBase::Discard()
{ {
#define MAX_BUFSIZE (10*1024) #define MAX_BUFSIZE (10*1024)
@@ -667,7 +541,7 @@ wxSocketBase& wxSocketBase::Discard()
m_reading = TRUE; m_reading = TRUE;
old_flags = m_flags; old_flags = m_flags;
SetFlags(NOWAIT); SetFlags(wxSOCKET_NOWAIT);
while (recv_size == MAX_BUFSIZE) while (recv_size == MAX_BUFSIZE)
{ {
@@ -730,11 +604,11 @@ void wxSocketBase::SaveState()
state = new wxSocketState(); state = new wxSocketState();
state->notify_state = m_notify_state; state->m_notify_state = m_notify_state;
state->evt_notify_state = m_neededreq; state->m_neededreq = m_neededreq;
state->socket_flags = m_flags; state->m_flags = m_flags;
state->c_callback = m_cbk; state->m_cbk = m_cbk;
state->c_callback_data = m_cdata; state->m_cdata = m_cdata;
m_states.Append(state); m_states.Append(state);
} }
@@ -750,11 +624,11 @@ void wxSocketBase::RestoreState()
state = (wxSocketState *)node->Data(); state = (wxSocketState *)node->Data();
SetFlags(state->socket_flags); SetFlags(state->m_flags);
m_neededreq = state->evt_notify_state; m_cbk = state->m_cbk;
m_cbk = state->c_callback; m_cdata = state->m_cdata;
m_cdata = state->c_callback_data; m_neededreq = state->m_neededreq;
Notify(state->notify_state); Notify(state->m_notify_state);
delete node; delete node;
delete state; delete state;
@@ -779,6 +653,9 @@ bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags fla
long timeout; long timeout;
int state = -1; int state = -1;
// Set this to TRUE to interrupt ongoing waits
m_interrupt = FALSE;
// Check for valid socket // Check for valid socket
if (!m_socket) if (!m_socket)
return FALSE; return FALSE;
@@ -811,7 +688,8 @@ bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags fla
// //
// Do this at least once (important if timeout == 0, when // Do this at least once (important if timeout == 0, when
// we are just polling) // we are just polling)
do //
while (state == -1)
{ {
result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG); result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG);
@@ -819,7 +697,6 @@ bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags fla
if (result & GSOCK_LOST_FLAG) if (result & GSOCK_LOST_FLAG)
{ {
timer.Stop(); timer.Stop();
m_defer_buffer = NULL;
Close(); Close();
return TRUE; return TRUE;
} }
@@ -833,24 +710,18 @@ bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags fla
return TRUE; return TRUE;
} }
// If we are in the middle of a R/W operation, do not propagate if ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
// to users.
if ( ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
&& (!m_writing) && (!m_reading) )
{ {
/* TODO: remove this timer.Stop();
if (m_defer_buffer == NULL) return TRUE;
*/
{
timer.Stop();
return TRUE;
}
} }
if (timeout != 0) // Wait more?
PROCESS_EVENTS(); if ((timeout == 0) || (m_interrupt))
break;
PROCESS_EVENTS();
} }
while ((state == -1) && timeout);
timer.Stop(); timer.Stop();
return FALSE; return FALSE;
@@ -965,41 +836,30 @@ void wxSocketBase::OnRequest(wxSocketNotify req_evt)
// fprintf(stderr, "%s: Entering OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt); // fprintf(stderr, "%s: Entering OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
// NOTE: this duplicates some of the code in _Wait (lost // NOTE: this duplicates some of the code in _Wait, (lost
// connection and connection establishment handling) but // connections and delayed connection establishment) but
// this doesn't hurt. It has to be here because maybe the // this doesn't hurt. It has to be here because maybe the
// WaitXXX are not being used, and it has to be in _Wait // WaitXXX are not being used, and it has to be in _Wait
// as well because the event might be a bit delayed. // as well because the event might be a bit delayed.
// //
switch(req_evt) switch (req_evt)
{ {
case wxSOCKET_CONNECTION: case wxSOCKET_CONNECTION :
m_establishing = FALSE; m_establishing = FALSE;
m_connected = TRUE; m_connected = TRUE;
break; break;
case wxSOCKET_LOST: case wxSOCKET_LOST:
m_defer_buffer = NULL;
Close(); Close();
break; break;
case wxSOCKET_INPUT:
case wxSOCKET_OUTPUT:
if (m_defer_buffer)
{
// fprintf(stderr, "%s: Habia buffer, evt %d skipped\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
DoDefer();
// Do not notify to user
return;
}
break;
}
// If we are in the middle of a R/W operation, do not // If we are in the middle of a R/W operation, do not
// propagate events to users. // propagate events to users.
if (((req_evt == wxSOCKET_INPUT) && m_reading) || //
((req_evt == wxSOCKET_OUTPUT) && m_writing)) case wxSOCKET_INPUT:
{ if (m_reading) return;
// fprintf(stderr, "%s: Swallowed evt %d\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
return; case wxSOCKET_OUTPUT:
if (m_writing) return;
} }
if (((m_neededreq & flag) == flag) && m_notify_state) if (((m_neededreq & flag) == flag) && m_notify_state)
@@ -1007,11 +867,12 @@ void wxSocketBase::OnRequest(wxSocketNotify req_evt)
// fprintf(stderr, "%s: Evt %d delivered\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt); // fprintf(stderr, "%s: Evt %d delivered\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
event.m_socket = this; event.m_socket = this;
event.m_skevt = req_evt; event.m_skevt = req_evt;
ProcessEvent(event); ProcessEvent(event); // XXX - should be PostEvent
OldOnNotify(req_evt);
OldOnNotify(req_evt);
if (m_cbk) if (m_cbk)
m_cbk(*this, req_evt, m_cdata); m_cbk(*this, req_evt, m_cdata);
} }
// fprintf(stderr, "%s: Exiting OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt); // fprintf(stderr, "%s: Exiting OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);