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:
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user