don't duplicate GSocket creation/destruction and shutdown code in BSD and Winsock implementations
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56926 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -163,15 +163,22 @@ private:
|
|||||||
class GSocketBase
|
class GSocketBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// static factory function
|
||||||
|
static GSocket *Create();
|
||||||
|
|
||||||
|
virtual ~GSocketBase();
|
||||||
|
|
||||||
GSocketEventFlags Select(GSocketEventFlags flags);
|
GSocketEventFlags Select(GSocketEventFlags flags);
|
||||||
|
|
||||||
|
virtual void Close() = 0;
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
SOCKET m_fd;
|
SOCKET m_fd;
|
||||||
#else
|
#else
|
||||||
int m_fd;
|
int m_fd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool m_ok;
|
|
||||||
int m_initialRecvBufferSize;
|
int m_initialRecvBufferSize;
|
||||||
int m_initialSendBufferSize;
|
int m_initialSendBufferSize;
|
||||||
|
|
||||||
@@ -196,6 +203,9 @@ public:
|
|||||||
GSocketEventFlags m_detected;
|
GSocketEventFlags m_detected;
|
||||||
GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
|
GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
|
||||||
char *m_data[GSOCK_MAX_EVENT];
|
char *m_data[GSOCK_MAX_EVENT];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GSocketBase();
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
#if defined(__WINDOWS__)
|
||||||
@@ -204,7 +214,6 @@ public:
|
|||||||
#include "wx/unix/gsockunx.h"
|
#include "wx/unix/gsockunx.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Global initializers */
|
/* Global initializers */
|
||||||
|
|
||||||
/* GSocket_Init() must be called at the beginning (but after calling
|
/* GSocket_Init() must be called at the beginning (but after calling
|
||||||
@@ -215,11 +224,6 @@ bool GSocket_Init();
|
|||||||
void GSocket_Cleanup();
|
void GSocket_Cleanup();
|
||||||
|
|
||||||
|
|
||||||
/* Constructors / Destructors */
|
|
||||||
|
|
||||||
GSocket *GSocket_new();
|
|
||||||
|
|
||||||
|
|
||||||
/* GAddress */
|
/* GAddress */
|
||||||
|
|
||||||
// Represents a socket endpoint, i.e. -- in spite of its name -- not an address
|
// Represents a socket endpoint, i.e. -- in spite of its name -- not an address
|
||||||
@@ -334,6 +338,13 @@ GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
|
|||||||
#define SOCKOPTLEN_T int
|
#define SOCKOPTLEN_T int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MSW defines this, Unices don't.
|
||||||
|
*/
|
||||||
|
#ifndef INVALID_SOCKET
|
||||||
|
#define INVALID_SOCKET (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* wxUSE_SOCKETS */
|
#endif /* wxUSE_SOCKETS */
|
||||||
|
|
||||||
#endif /* _WX_GSOCKET_H_ */
|
#endif /* _WX_GSOCKET_H_ */
|
||||||
|
@@ -27,11 +27,10 @@
|
|||||||
class GSocket : public GSocketBase
|
class GSocket : public GSocketBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GSocket();
|
GSocket() : GSocketBase() { m_msgnumber = 0; }
|
||||||
~GSocket();
|
|
||||||
bool IsOk() { return m_ok; }
|
virtual void Close();
|
||||||
void Close();
|
|
||||||
void Shutdown();
|
|
||||||
GSocketError SetLocal(GAddress *address);
|
GSocketError SetLocal(GAddress *address);
|
||||||
GSocketError SetPeer(GAddress *address);
|
GSocketError SetPeer(GAddress *address);
|
||||||
GAddress *GetLocal();
|
GAddress *GetLocal();
|
||||||
|
@@ -17,10 +17,9 @@ class GSocket : public GSocketBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GSocket();
|
GSocket();
|
||||||
virtual ~GSocket();
|
~GSocket();
|
||||||
bool IsOk() { return m_ok; }
|
virtual void Close();
|
||||||
void Close();
|
virtual void Shutdown();
|
||||||
void Shutdown();
|
|
||||||
GSocketError SetLocal(GAddress *address);
|
GSocketError SetLocal(GAddress *address);
|
||||||
GSocketError SetPeer(GAddress *address);
|
GSocketError SetPeer(GAddress *address);
|
||||||
GAddress *GetLocal();
|
GAddress *GetLocal();
|
||||||
@@ -45,8 +44,8 @@ public:
|
|||||||
const void *optval, int optlen);
|
const void *optval, int optlen);
|
||||||
//attach or detach from main loop
|
//attach or detach from main loop
|
||||||
void Notify(bool flag);
|
void Notify(bool flag);
|
||||||
virtual void Detected_Read();
|
void Detected_Read();
|
||||||
virtual void Detected_Write();
|
void Detected_Write();
|
||||||
void SetInitialSocketBuffers(int recv, int send)
|
void SetInitialSocketBuffers(int recv, int send)
|
||||||
{
|
{
|
||||||
m_initialRecvBufferSize = recv;
|
m_initialRecvBufferSize = recv;
|
||||||
|
@@ -152,6 +152,86 @@ void GSocketManager::Init()
|
|||||||
ms_manager = app->GetTraits()->GetSocketManager();
|
ms_manager = app->GetTraits()->GetSocketManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==========================================================================
|
||||||
|
// GSocketBase
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
GSocket *GSocketBase::Create()
|
||||||
|
{
|
||||||
|
GSocket * const newsocket = new GSocket();
|
||||||
|
if ( !GSocketManager::Get()->Init_Socket(newsocket) )
|
||||||
|
{
|
||||||
|
delete newsocket;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newsocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
GSocketBase::GSocketBase()
|
||||||
|
{
|
||||||
|
m_fd = INVALID_SOCKET;
|
||||||
|
m_detected = 0;
|
||||||
|
m_local = NULL;
|
||||||
|
m_peer = NULL;
|
||||||
|
m_error = GSOCK_NOERROR;
|
||||||
|
m_server = false;
|
||||||
|
m_stream = true;
|
||||||
|
m_non_blocking = false;
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
m_timeout.tv_sec = 10 * 60; /* 10 minutes */
|
||||||
|
m_timeout.tv_usec = 0;
|
||||||
|
#else
|
||||||
|
m_timeout = 10*60*1000; /* 10 minutes * 60 sec * 1000 millisec */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_establishing = false;
|
||||||
|
m_reusable = false;
|
||||||
|
m_broadcast = false;
|
||||||
|
m_dobind = true;
|
||||||
|
m_initialRecvBufferSize = -1;
|
||||||
|
m_initialSendBufferSize = -1;
|
||||||
|
|
||||||
|
for ( int i = 0; i < GSOCK_MAX_EVENT; i++ )
|
||||||
|
m_cbacks[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GSocketBase::~GSocketBase()
|
||||||
|
{
|
||||||
|
if (m_fd != INVALID_SOCKET)
|
||||||
|
Shutdown();
|
||||||
|
|
||||||
|
if (m_local)
|
||||||
|
GAddress_destroy(m_local);
|
||||||
|
|
||||||
|
if (m_peer)
|
||||||
|
GAddress_destroy(m_peer);
|
||||||
|
|
||||||
|
// cast is ok as all GSocketBase objects we have in our code are really
|
||||||
|
// GSockets
|
||||||
|
GSocketManager::Get()->Destroy_Socket(static_cast<GSocket *>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GSocket_Shutdown:
|
||||||
|
* Disallow further read/write operations on this socket, close
|
||||||
|
* the fd and disable all callbacks.
|
||||||
|
*/
|
||||||
|
void GSocketBase::Shutdown()
|
||||||
|
{
|
||||||
|
if ( m_fd != INVALID_SOCKET )
|
||||||
|
{
|
||||||
|
shutdown(m_fd, 1 /* SD_SEND */);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable GUI callbacks */
|
||||||
|
for ( int evt = 0; evt < GSOCK_MAX_EVENT; evt++ )
|
||||||
|
m_cbacks[evt] = NULL;
|
||||||
|
|
||||||
|
m_detected = GSOCK_LOST_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// wxSocketBase
|
// wxSocketBase
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@@ -1243,7 +1323,7 @@ wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
|
|||||||
{
|
{
|
||||||
wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
|
wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
|
||||||
|
|
||||||
m_socket = GSocket_new();
|
m_socket = GSocket::Create();
|
||||||
|
|
||||||
if (!m_socket)
|
if (!m_socket)
|
||||||
{
|
{
|
||||||
@@ -1406,7 +1486,7 @@ bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
|
|||||||
delete m_socket;
|
delete m_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_socket = GSocket_new();
|
m_socket = GSocket::Create();
|
||||||
m_connected = false;
|
m_connected = false;
|
||||||
m_establishing = false;
|
m_establishing = false;
|
||||||
|
|
||||||
@@ -1521,7 +1601,7 @@ wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
|
|||||||
: wxSocketBase( flags, wxSOCKET_DATAGRAM )
|
: wxSocketBase( flags, wxSOCKET_DATAGRAM )
|
||||||
{
|
{
|
||||||
// Create the socket
|
// Create the socket
|
||||||
m_socket = GSocket_new();
|
m_socket = GSocket::Create();
|
||||||
|
|
||||||
if (!m_socket)
|
if (!m_socket)
|
||||||
{
|
{
|
||||||
|
@@ -110,34 +110,6 @@ void GSocket_Cleanup()
|
|||||||
|
|
||||||
/* Constructors / Destructors for GSocket */
|
/* Constructors / Destructors for GSocket */
|
||||||
|
|
||||||
GSocket::GSocket()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
m_fd = INVALID_SOCKET;
|
|
||||||
for (i = 0; i < GSOCK_MAX_EVENT; i++)
|
|
||||||
{
|
|
||||||
m_cbacks[i] = NULL;
|
|
||||||
}
|
|
||||||
m_detected = 0;
|
|
||||||
m_local = NULL;
|
|
||||||
m_peer = NULL;
|
|
||||||
m_error = GSOCK_NOERROR;
|
|
||||||
m_server = false;
|
|
||||||
m_stream = true;
|
|
||||||
m_non_blocking = false;
|
|
||||||
m_timeout.tv_sec = 10 * 60; /* 10 minutes */
|
|
||||||
m_timeout.tv_usec = 0;
|
|
||||||
m_establishing = false;
|
|
||||||
m_reusable = false;
|
|
||||||
m_broadcast = false;
|
|
||||||
m_dobind = true;
|
|
||||||
m_initialRecvBufferSize = -1;
|
|
||||||
m_initialSendBufferSize = -1;
|
|
||||||
|
|
||||||
m_ok = GSocketManager::Get()->Init_Socket(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSocket::Close()
|
void GSocket::Close()
|
||||||
{
|
{
|
||||||
GSocketManager::Get()->Disable_Events(this);
|
GSocketManager::Get()->Disable_Events(this);
|
||||||
@@ -145,44 +117,6 @@ void GSocket::Close()
|
|||||||
m_fd = INVALID_SOCKET;
|
m_fd = INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSocket::~GSocket()
|
|
||||||
{
|
|
||||||
GSocketManager::Get()->Destroy_Socket(this);
|
|
||||||
|
|
||||||
/* Check that the socket is really shutdowned */
|
|
||||||
if (m_fd != INVALID_SOCKET)
|
|
||||||
Shutdown();
|
|
||||||
|
|
||||||
/* Destroy private addresses */
|
|
||||||
if (m_local)
|
|
||||||
GAddress_destroy(m_local);
|
|
||||||
|
|
||||||
if (m_peer)
|
|
||||||
GAddress_destroy(m_peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* GSocket_Shutdown:
|
|
||||||
* Disallow further read/write operations on this socket, close
|
|
||||||
* the fd and disable all callbacks.
|
|
||||||
*/
|
|
||||||
void GSocket::Shutdown()
|
|
||||||
{
|
|
||||||
int evt;
|
|
||||||
|
|
||||||
/* If socket has been created, shutdown it */
|
|
||||||
if (m_fd != INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
shutdown(m_fd, 1 /* SD_SEND */);
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable GUI callbacks */
|
|
||||||
for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
|
|
||||||
m_cbacks[evt] = NULL;
|
|
||||||
|
|
||||||
m_detected = GSOCK_LOST_FLAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Address handling */
|
/* Address handling */
|
||||||
|
|
||||||
/* GSocket_SetLocal:
|
/* GSocket_SetLocal:
|
||||||
@@ -393,7 +327,7 @@ GSocket *GSocket::WaitConnection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create a GSocket object for the new connection */
|
/* Create a GSocket object for the new connection */
|
||||||
connection = GSocket_new();
|
connection = GSocket::Create();
|
||||||
|
|
||||||
if (!connection)
|
if (!connection)
|
||||||
{
|
{
|
||||||
@@ -1032,17 +966,6 @@ int GSocket::Send_Dgram(const char *buffer, int size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compatibility functions for GSocket */
|
|
||||||
GSocket *GSocket_new()
|
|
||||||
{
|
|
||||||
GSocket *newsocket = new GSocket();
|
|
||||||
if(newsocket->IsOk())
|
|
||||||
return newsocket;
|
|
||||||
delete newsocket;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
* GAddress
|
* GAddress
|
||||||
|
@@ -313,10 +313,10 @@ void GSocketMSWManager::Destroy_Socket(GSocket *socket)
|
|||||||
{
|
{
|
||||||
/* Remove the socket from the list */
|
/* Remove the socket from the list */
|
||||||
EnterCriticalSection(&critical);
|
EnterCriticalSection(&critical);
|
||||||
if ( socket->IsOk() )
|
|
||||||
{
|
|
||||||
const int msgnum = socket->m_msgnumber;
|
|
||||||
|
|
||||||
|
const int msgnum = socket->m_msgnumber;
|
||||||
|
if ( msgnum )
|
||||||
|
{
|
||||||
// we need to remove any pending messages for this socket to avoid having
|
// we need to remove any pending messages for this socket to avoid having
|
||||||
// them sent to a new socket which could reuse the same message number as
|
// them sent to a new socket which could reuse the same message number as
|
||||||
// soon as we destroy this one
|
// soon as we destroy this one
|
||||||
@@ -326,6 +326,7 @@ void GSocketMSWManager::Destroy_Socket(GSocket *socket)
|
|||||||
|
|
||||||
socketList[msgnum - WM_USER] = NULL;
|
socketList[msgnum - WM_USER] = NULL;
|
||||||
}
|
}
|
||||||
|
//else: the socket has never been created successfully
|
||||||
|
|
||||||
LeaveCriticalSection(&critical);
|
LeaveCriticalSection(&critical);
|
||||||
}
|
}
|
||||||
|
@@ -134,13 +134,6 @@ int _System soclose(int);
|
|||||||
#define SOCKOPTLEN_T WX_SOCKLEN_T
|
#define SOCKOPTLEN_T WX_SOCKLEN_T
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* MSW defines this, Unices don't.
|
|
||||||
*/
|
|
||||||
#ifndef INVALID_SOCKET
|
|
||||||
#define INVALID_SOCKET -1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* UnixWare reportedly needs this for FIONBIO definition */
|
/* UnixWare reportedly needs this for FIONBIO definition */
|
||||||
#ifdef __UNIXWARE__
|
#ifdef __UNIXWARE__
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
@@ -476,34 +469,10 @@ void GSocket_Cleanup()
|
|||||||
|
|
||||||
GSocket::GSocket()
|
GSocket::GSocket()
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
m_fd = INVALID_SOCKET;
|
|
||||||
m_handler = NULL;
|
m_handler = NULL;
|
||||||
|
|
||||||
for (i=0;i<GSOCK_MAX_EVENT;i++)
|
|
||||||
{
|
|
||||||
m_cbacks[i] = NULL;
|
|
||||||
}
|
|
||||||
m_detected = 0;
|
|
||||||
m_local = NULL;
|
|
||||||
m_peer = NULL;
|
|
||||||
m_error = GSOCK_NOERROR;
|
|
||||||
m_server = false;
|
|
||||||
m_stream = true;
|
|
||||||
m_gui_dependent = NULL;
|
m_gui_dependent = NULL;
|
||||||
m_non_blocking = false;
|
|
||||||
m_reusable = false;
|
|
||||||
m_broadcast = false;
|
|
||||||
m_dobind = true;
|
|
||||||
m_timeout = 10*60*1000;
|
|
||||||
/* 10 minutes * 60 sec * 1000 millisec */
|
|
||||||
m_establishing = false;
|
|
||||||
m_use_events = false;
|
m_use_events = false;
|
||||||
m_initialRecvBufferSize = -1;
|
|
||||||
m_initialSendBufferSize = -1;
|
|
||||||
|
|
||||||
m_ok = GSocketManager::Get()->Init_Socket(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSocket::Close()
|
void GSocket::Close()
|
||||||
@@ -526,23 +495,7 @@ void GSocket::Close()
|
|||||||
|
|
||||||
GSocket::~GSocket()
|
GSocket::~GSocket()
|
||||||
{
|
{
|
||||||
assert(this);
|
|
||||||
|
|
||||||
/* Check that the socket is really shutdowned */
|
|
||||||
if (m_fd != INVALID_SOCKET)
|
|
||||||
Shutdown();
|
|
||||||
|
|
||||||
GSocketManager::Get()->Destroy_Socket(this);
|
|
||||||
|
|
||||||
delete m_handler;
|
delete m_handler;
|
||||||
|
|
||||||
/* Destroy private addresses */
|
|
||||||
if (m_local)
|
|
||||||
GAddress_destroy(m_local);
|
|
||||||
|
|
||||||
if (m_peer)
|
|
||||||
GAddress_destroy(m_peer);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GSocket_Shutdown:
|
/* GSocket_Shutdown:
|
||||||
@@ -551,26 +504,11 @@ GSocket::~GSocket()
|
|||||||
*/
|
*/
|
||||||
void GSocket::Shutdown()
|
void GSocket::Shutdown()
|
||||||
{
|
{
|
||||||
int evt;
|
/* Don't allow events to fire after socket has been closed */
|
||||||
|
if (m_use_events)
|
||||||
|
DisableEvents();
|
||||||
|
|
||||||
assert(this);
|
GSocketBase::Shutdown();
|
||||||
|
|
||||||
/* Don't allow events to fire after socket has been closed */
|
|
||||||
if (m_use_events)
|
|
||||||
DisableEvents();
|
|
||||||
|
|
||||||
/* If socket has been created, shutdown it */
|
|
||||||
if (m_fd != INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
shutdown(m_fd, 1);
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable GUI callbacks */
|
|
||||||
for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
|
|
||||||
m_cbacks[evt] = NULL;
|
|
||||||
|
|
||||||
m_detected = GSOCK_LOST_FLAG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Address handling */
|
/* Address handling */
|
||||||
@@ -803,7 +741,7 @@ GSocket *GSocket::WaitConnection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create a GSocket object for the new connection */
|
/* Create a GSocket object for the new connection */
|
||||||
connection = GSocket_new();
|
connection = GSocket::Create();
|
||||||
|
|
||||||
if (!connection)
|
if (!connection)
|
||||||
{
|
{
|
||||||
@@ -1743,18 +1681,6 @@ void GSocket::Detected_Write()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compatibility functions for GSocket */
|
|
||||||
GSocket *GSocket_new(void)
|
|
||||||
{
|
|
||||||
GSocket *newsocket = new GSocket();
|
|
||||||
if (newsocket->IsOk())
|
|
||||||
return newsocket;
|
|
||||||
|
|
||||||
delete newsocket;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
* GAddress
|
* GAddress
|
||||||
|
Reference in New Issue
Block a user