From eb97543d28f634b302038aa58ecd6c965cf1efb9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 23 Nov 2008 01:44:50 +0000 Subject: [PATCH] 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 --- include/wx/gsocket.h | 25 +++++++---- include/wx/msw/gsockmsw.h | 9 ++-- include/wx/unix/gsockunx.h | 11 +++-- src/common/socket.cpp | 86 ++++++++++++++++++++++++++++++++++++-- src/msw/gsocket.cpp | 79 +--------------------------------- src/msw/gsockmsw.cpp | 7 ++-- src/unix/gsocket.cpp | 84 +++---------------------------------- 7 files changed, 120 insertions(+), 181 deletions(-) diff --git a/include/wx/gsocket.h b/include/wx/gsocket.h index a587ece8c0..70fd12f299 100644 --- a/include/wx/gsocket.h +++ b/include/wx/gsocket.h @@ -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_ */ diff --git a/include/wx/msw/gsockmsw.h b/include/wx/msw/gsockmsw.h index 36e7bfbb87..94f622064b 100644 --- a/include/wx/msw/gsockmsw.h +++ b/include/wx/msw/gsockmsw.h @@ -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(); diff --git a/include/wx/unix/gsockunx.h b/include/wx/unix/gsockunx.h index c6459aab09..3741595542 100644 --- a/include/wx/unix/gsockunx.h +++ b/include/wx/unix/gsockunx.h @@ -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; diff --git a/src/common/socket.cpp b/src/common/socket.cpp index d7acc0b671..266e81cce7 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -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(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) { diff --git a/src/msw/gsocket.cpp b/src/msw/gsocket.cpp index 1730fc7fc7..5730a6cf18 100644 --- a/src/msw/gsocket.cpp +++ b/src/msw/gsocket.cpp @@ -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 diff --git a/src/msw/gsockmsw.cpp b/src/msw/gsockmsw.cpp index 489feff570..61ba71bdfe 100644 --- a/src/msw/gsockmsw.cpp +++ b/src/msw/gsockmsw.cpp @@ -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); } diff --git a/src/unix/gsocket.cpp b/src/unix/gsocket.cpp index 97105ca534..226f46ad0d 100644 --- a/src/unix/gsocket.cpp +++ b/src/unix/gsocket.cpp @@ -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 @@ -476,34 +469,10 @@ void GSocket_Cleanup() GSocket::GSocket() { - int i; - - m_fd = INVALID_SOCKET; m_handler = NULL; - for (i=0;iInit_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; + /* Don't allow events to fire after socket has been closed */ + if (m_use_events) + DisableEvents(); - 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 -- 2.45.2