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:
Vadim Zeitlin
2008-11-23 01:44:50 +00:00
parent afe0e40097
commit eb97543d28
7 changed files with 120 additions and 181 deletions

View File

@@ -163,15 +163,22 @@ private:
class GSocketBase
{
public:
// static factory function
static GSocket *Create();
virtual ~GSocketBase();
GSocketEventFlags Select(GSocketEventFlags flags);
virtual void Close() = 0;
virtual void Shutdown();
#ifdef __WINDOWS__
SOCKET m_fd;
#else
int m_fd;
#endif
bool m_ok;
int m_initialRecvBufferSize;
int m_initialSendBufferSize;
@@ -196,6 +203,9 @@ public:
GSocketEventFlags m_detected;
GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
char *m_data[GSOCK_MAX_EVENT];
protected:
GSocketBase();
};
#if defined(__WINDOWS__)
@@ -204,7 +214,6 @@ public:
#include "wx/unix/gsockunx.h"
#endif
/* Global initializers */
/* GSocket_Init() must be called at the beginning (but after calling
@@ -215,11 +224,6 @@ bool GSocket_Init();
void GSocket_Cleanup();
/* Constructors / Destructors */
GSocket *GSocket_new();
/* GAddress */
// 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
#endif
/*
* MSW defines this, Unices don't.
*/
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (-1)
#endif
#endif /* wxUSE_SOCKETS */
#endif /* _WX_GSOCKET_H_ */

View File

@@ -27,11 +27,10 @@
class GSocket : public GSocketBase
{
public:
GSocket();
~GSocket();
bool IsOk() { return m_ok; }
void Close();
void Shutdown();
GSocket() : GSocketBase() { m_msgnumber = 0; }
virtual void Close();
GSocketError SetLocal(GAddress *address);
GSocketError SetPeer(GAddress *address);
GAddress *GetLocal();

View File

@@ -17,10 +17,9 @@ class GSocket : public GSocketBase
{
public:
GSocket();
virtual ~GSocket();
bool IsOk() { return m_ok; }
void Close();
void Shutdown();
~GSocket();
virtual void Close();
virtual void Shutdown();
GSocketError SetLocal(GAddress *address);
GSocketError SetPeer(GAddress *address);
GAddress *GetLocal();
@@ -45,8 +44,8 @@ public:
const void *optval, int optlen);
//attach or detach from main loop
void Notify(bool flag);
virtual void Detected_Read();
virtual void Detected_Write();
void Detected_Read();
void Detected_Write();
void SetInitialSocketBuffers(int recv, int send)
{
m_initialRecvBufferSize = recv;

View File

@@ -152,6 +152,86 @@ void GSocketManager::Init()
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
// ==========================================================================
@@ -1243,7 +1323,7 @@ wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
{
wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
m_socket = GSocket_new();
m_socket = GSocket::Create();
if (!m_socket)
{
@@ -1406,7 +1486,7 @@ bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
delete m_socket;
}
m_socket = GSocket_new();
m_socket = GSocket::Create();
m_connected = false;
m_establishing = false;
@@ -1521,7 +1601,7 @@ wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
: wxSocketBase( flags, wxSOCKET_DATAGRAM )
{
// Create the socket
m_socket = GSocket_new();
m_socket = GSocket::Create();
if (!m_socket)
{

View File

@@ -110,34 +110,6 @@ void GSocket_Cleanup()
/* 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()
{
GSocketManager::Get()->Disable_Events(this);
@@ -145,44 +117,6 @@ void GSocket::Close()
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 */
/* GSocket_SetLocal:
@@ -393,7 +327,7 @@ GSocket *GSocket::WaitConnection()
}
/* Create a GSocket object for the new connection */
connection = GSocket_new();
connection = GSocket::Create();
if (!connection)
{
@@ -1032,17 +966,6 @@ int GSocket::Send_Dgram(const char *buffer, int size)
return ret;
}
/* Compatibility functions for GSocket */
GSocket *GSocket_new()
{
GSocket *newsocket = new GSocket();
if(newsocket->IsOk())
return newsocket;
delete newsocket;
return NULL;
}
/*
* -------------------------------------------------------------------------
* GAddress

View File

@@ -313,10 +313,10 @@ void GSocketMSWManager::Destroy_Socket(GSocket *socket)
{
/* Remove the socket from the list */
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
// them sent to a new socket which could reuse the same message number as
// soon as we destroy this one
@@ -326,6 +326,7 @@ void GSocketMSWManager::Destroy_Socket(GSocket *socket)
socketList[msgnum - WM_USER] = NULL;
}
//else: the socket has never been created successfully
LeaveCriticalSection(&critical);
}

View File

@@ -134,13 +134,6 @@ int _System soclose(int);
#define SOCKOPTLEN_T WX_SOCKLEN_T
#endif
/*
* MSW defines this, Unices don't.
*/
#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif
/* UnixWare reportedly needs this for FIONBIO definition */
#ifdef __UNIXWARE__
#include <sys/filio.h>
@@ -476,34 +469,10 @@ void GSocket_Cleanup()
GSocket::GSocket()
{
int i;
m_fd = INVALID_SOCKET;
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_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_initialRecvBufferSize = -1;
m_initialSendBufferSize = -1;
m_ok = GSocketManager::Get()->Init_Socket(this);
}
void GSocket::Close()
@@ -526,23 +495,7 @@ void GSocket::Close()
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;
/* Destroy private addresses */
if (m_local)
GAddress_destroy(m_local);
if (m_peer)
GAddress_destroy(m_peer);
}
/* GSocket_Shutdown:
@@ -551,26 +504,11 @@ GSocket::~GSocket()
*/
void GSocket::Shutdown()
{
int evt;
assert(this);
/* 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;
GSocketBase::Shutdown();
}
/* Address handling */
@@ -803,7 +741,7 @@ GSocket *GSocket::WaitConnection()
}
/* Create a GSocket object for the new connection */
connection = GSocket_new();
connection = GSocket::Create();
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