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 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_ */

View File

@@ -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();

View File

@@ -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;

View File

@@ -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)
{ {

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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