X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0834112f89c4c5da7864e17e6f483ce296798ce6..415ca026b4d66c4c43ef5724dbf2072ad433eb1f:/src/common/sckipc.cpp diff --git a/src/common/sckipc.cpp b/src/common/sckipc.cpp index 488ea062ba..3fea37e1ec 100644 --- a/src/common/sckipc.cpp +++ b/src/common/sckipc.cpp @@ -4,6 +4,7 @@ // Author: Julian Smart // Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998 // Guillermo Rodriguez (updated for wxSocket v2) Jan 2000 +// (callbacks deprecated) Mar 2000 // Created: 1993 // RCS-ID: $Id$ // Copyright: (c) Julian Smart 1993 @@ -12,6 +13,14 @@ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ========================================================================== +// declarations +// ========================================================================== + +// -------------------------------------------------------------------------- +// headers +// -------------------------------------------------------------------------- + #ifdef __GNUG__ #pragma implementation "sckipc.h" #endif @@ -23,30 +32,34 @@ #pragma hdrstop #endif -#if wxUSE_SOCKETS - #ifndef WX_PRECOMP +#include "wx/defs.h" #endif +#if wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS + #include #include #include "wx/socket.h" #include "wx/sckipc.h" +#include "wx/module.h" +#include "wx/event.h" #include "wx/log.h" #ifdef __BORLANDC__ #pragma hdrstop #endif -IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase) -IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase) -IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection, wxConnectionBase) +// -------------------------------------------------------------------------- +// macros and constants +// -------------------------------------------------------------------------- // It seems to be already defined somewhere in the Xt includes. #ifndef __XT__ // Message codes -enum { +enum +{ IPC_EXECUTE = 1, IPC_REQUEST, IPC_POKE, @@ -61,19 +74,46 @@ enum { }; #endif -void Server_OnRequest(wxSocketServer& server, - wxSocketNotify evt, - char *cdata); -void Client_OnRequest(wxSocketBase& sock, - wxSocketNotify evt, - char *cdata); -// --------------------------------------------------------------------------- +// All sockets will be created with the following flags +#define SCKIPC_FLAGS (wxSOCKET_WAITALL) + +// -------------------------------------------------------------------------- +// wxTCPEventHandler stuff (private class) +// -------------------------------------------------------------------------- + +class wxTCPEventHandler : public wxEvtHandler +{ +public: + wxTCPEventHandler() : wxEvtHandler() {}; + + void Client_OnRequest(wxSocketEvent& event); + void Server_OnRequest(wxSocketEvent& event); + + DECLARE_EVENT_TABLE() +}; + +enum +{ + _CLIENT_ONREQUEST_ID = 1000, + _SERVER_ONREQUEST_ID +}; + +static wxTCPEventHandler *gs_handler = NULL; + +// ========================================================================== +// implementation +// ========================================================================== + +IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase) +IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase) +IMPLEMENT_CLASS(wxTCPConnection, wxConnectionBase) + +// -------------------------------------------------------------------------- // wxTCPClient -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- -wxTCPClient::wxTCPClient () - : wxClientBase() +wxTCPClient::wxTCPClient () : wxClientBase() { } @@ -92,7 +132,7 @@ wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host, const wxString& server_name, const wxString& topic) { - wxSocketClient *client = new wxSocketClient(); + wxSocketClient *client = new wxSocketClient(SCKIPC_FLAGS); wxSocketStream *stream = new wxSocketStream(*client); wxDataInputStream *data_is = new wxDataInputStream(*stream); wxDataOutputStream *data_os = new wxDataOutputStream(*stream); @@ -118,70 +158,91 @@ wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host, if (connection) { - if (!connection->IsKindOf(CLASSINFO(wxTCPConnection))) - { - delete connection; - // and fall through to delete everything else - } - else + if (connection->IsKindOf(CLASSINFO(wxTCPConnection))) { connection->m_topic = topic; connection->m_sock = client; connection->m_sockstrm = stream; connection->m_codeci = data_is; connection->m_codeco = data_os; - client->Callback(Client_OnRequest); - client->CallbackData((char *)connection); + client->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID); + client->SetClientData(connection); client->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG); client->Notify(TRUE); return connection; } + else + { + delete connection; + // and fall through to delete everything else + } } } } - // something went wrong + // Something went wrong, delete everything delete data_is; delete data_os; delete stream; - delete client; + client->Destroy(); + return NULL; } wxConnectionBase *wxTCPClient::OnMakeConnection() { - return new wxTCPConnection; + return new wxTCPConnection(); } -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- // wxTCPServer -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- -wxTCPServer::wxTCPServer () - : wxServerBase() +wxTCPServer::wxTCPServer () : wxServerBase() { + m_server = NULL; } -bool wxTCPServer::Create(const wxString& server_name) +bool wxTCPServer::Create(const wxString& serverName) { + // Destroy previous server, if any + if (m_server) + { + m_server->SetClientData(NULL); + m_server->Destroy(); + m_server = NULL; + } + + // wxIPV4address defaults to INADDR_ANY:0 wxIPV4address addr; - wxSocketServer *server; + addr.Service(serverName); - addr.LocalHost(); // GRG - addr.Service(server_name); + // Create a socket listening on the specified port + m_server = new wxSocketServer(addr, SCKIPC_FLAGS); - // Create a socket listening on specified port - server = new wxSocketServer(addr); - server->Callback((wxSocketBase::wxSockCbk)Server_OnRequest); - server->CallbackData((char *)this); - server->SetNotify(wxSOCKET_CONNECTION_FLAG); - server->Notify(TRUE); // GRG + if (!m_server->Ok()) + { + m_server->Destroy(); + m_server = NULL; + + return FALSE; + } + + m_server->SetEventHandler(*gs_handler, _SERVER_ONREQUEST_ID); + m_server->SetClientData(this); + m_server->SetNotify(wxSOCKET_CONNECTION_FLAG); + m_server->Notify(TRUE); return TRUE; } wxTCPServer::~wxTCPServer() { + if (m_server) + { + m_server->SetClientData(NULL); + m_server->Destroy(); + } } wxConnectionBase *wxTCPServer::OnAcceptConnection( const wxString& WXUNUSED(topic) ) @@ -189,14 +250,16 @@ wxConnectionBase *wxTCPServer::OnAcceptConnection( const wxString& WXUNUSED(topi return new wxTCPConnection(); } -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- // wxTCPConnection -// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- -wxTCPConnection::wxTCPConnection () - : wxConnectionBase(), - m_sock(NULL), m_sockstrm(NULL), m_codeci(NULL), m_codeco(NULL) +wxTCPConnection::wxTCPConnection () : wxConnectionBase() { + m_sock = NULL; + m_sockstrm = NULL; + m_codeci = NULL; + m_codeco = NULL; } wxTCPConnection::wxTCPConnection(char * WXUNUSED(buffer), int WXUNUSED(size)) @@ -205,10 +268,15 @@ wxTCPConnection::wxTCPConnection(char * WXUNUSED(buffer), int WXUNUSED(size)) wxTCPConnection::~wxTCPConnection () { - wxDELETE(m_sock); wxDELETE(m_codeci); wxDELETE(m_codeco); wxDELETE(m_sockstrm); + + if (m_sock) + { + m_sock->SetClientData(NULL); + m_sock->Destroy(); + } } void wxTCPConnection::Compress(bool WXUNUSED(on)) @@ -221,6 +289,7 @@ bool wxTCPConnection::Disconnect () { // Send the the disconnect message to the peer. m_codeco->Write8(IPC_DISCONNECT); + m_sock->Notify(FALSE); m_sock->Close(); return TRUE; @@ -236,7 +305,7 @@ bool wxTCPConnection::Execute(const wxChar *data, int size, wxIPCFormat format) m_codeco->Write8(format); if (size < 0) - size = strlen(data) + 1; // includes final NUL + size = wxStrlen(data) + 1; // includes final NUL m_codeco->Write32(size); m_sockstrm->Write(data, size); @@ -284,7 +353,7 @@ bool wxTCPConnection::Poke (const wxString& item, wxChar *data, int size, wxIPCF m_codeco->Write8(format); if (size < 0) - size = strlen(data) + 1; // includes final NUL + size = wxStrlen(data) + 1; // includes final NUL m_codeco->Write32(size); m_sockstrm->Write(data, size); @@ -340,7 +409,7 @@ bool wxTCPConnection::Advise (const wxString& item, m_codeco->Write8(format); if (size < 0) - size = strlen(data) + 1; // includes final NUL + size = wxStrlen(data) + 1; // includes final NUL m_codeco->Write32(size); m_sockstrm->Write(data, size); @@ -348,21 +417,37 @@ bool wxTCPConnection::Advise (const wxString& item, return TRUE; } -void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt, - char *cdata) +// -------------------------------------------------------------------------- +// wxTCPEventHandler (private class) +// -------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxTCPEventHandler, wxEvtHandler) + EVT_SOCKET(_CLIENT_ONREQUEST_ID, wxTCPEventHandler::Client_OnRequest) + EVT_SOCKET(_SERVER_ONREQUEST_ID, wxTCPEventHandler::Server_OnRequest) +END_EVENT_TABLE() + +void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event) { + wxSocketBase *sock = event.GetSocket(); + wxSocketNotify evt = event.GetSocketEvent(); + wxTCPConnection *connection = (wxTCPConnection *)(sock->GetClientData()); + + // This socket is being deleted; skip this event + if (!connection) + return; + int msg = 0; - wxTCPConnection *connection = (wxTCPConnection *)cdata; wxDataInputStream *codeci; wxDataOutputStream *codeco; wxSocketStream *sockstrm; wxString topic_name = connection->m_topic; wxString item; - // The socket handler signals us that we lost the connection: destroy all. + // We lost the connection: destroy everything if (evt == wxSOCKET_LOST) { - sock.Close(); + sock->Notify(FALSE); + sock->Close(); connection->OnDisconnect(); return; } @@ -477,7 +562,8 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt, } case IPC_DISCONNECT: { - sock.Close(); + sock->Notify(FALSE); + sock->Close(); connection->OnDisconnect(); break; } @@ -487,25 +573,29 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt, } } -void Server_OnRequest(wxSocketServer& server, - wxSocketNotify evt, char *cdata) +void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event) { - wxTCPServer *ipcserv = (wxTCPServer *)cdata; - wxSocketStream *stream; - wxDataInputStream *codeci; - wxDataOutputStream *codeco; + wxSocketServer *server = (wxSocketServer *) event.GetSocket(); + wxTCPServer *ipcserv = (wxTCPServer *) server->GetClientData(); - if (evt != wxSOCKET_CONNECTION) + // This socket is being deleted; skip this event + if (!ipcserv) return; - /* Accept the connection, getting a new socket */ - wxSocketBase *sock = server.Accept(); + if (event.GetSocketEvent() != wxSOCKET_CONNECTION) + return; + + // Accept the connection, getting a new socket + wxSocketBase *sock = server->Accept(); if (!sock->Ok()) + { + sock->Destroy(); return; + } - stream = new wxSocketStream(*sock); - codeci = new wxDataInputStream(*stream); - codeco = new wxDataOutputStream(*stream); + wxSocketStream *stream = new wxSocketStream(*sock); + wxDataInputStream *codeci = new wxDataInputStream(*stream); + wxDataOutputStream *codeco = new wxDataOutputStream(*stream); int msg; msg = codeci->Read8(); @@ -515,36 +605,58 @@ void Server_OnRequest(wxSocketServer& server, wxString topic_name; topic_name = codeci->ReadString(); - /* Register new socket with the notifier */ wxTCPConnection *new_connection = (wxTCPConnection *)ipcserv->OnAcceptConnection (topic_name); + if (new_connection) { - if (!new_connection->IsKindOf(CLASSINFO(wxTCPConnection))) + if (new_connection->IsKindOf(CLASSINFO(wxTCPConnection))) { - delete new_connection; - codeco->Write8(IPC_FAIL); + // Acknowledge success + codeco->Write8(IPC_CONNECT); + new_connection->m_topic = topic_name; + new_connection->m_sock = sock; + new_connection->m_sockstrm = stream; + new_connection->m_codeci = codeci; + new_connection->m_codeco = codeco; + sock->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID); + sock->SetClientData(new_connection); + sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG); + sock->Notify(TRUE); return; } - // Acknowledge success - codeco->Write8(IPC_CONNECT); - new_connection->m_topic = topic_name; - new_connection->m_sock = sock; - new_connection->m_sockstrm = stream; - new_connection->m_codeci = codeci; - new_connection->m_codeco = codeco; - sock->Callback(Client_OnRequest); - sock->CallbackData((char *)new_connection); - sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG); - sock->Notify(TRUE); - } - else - { - // Send failure message - codeco->Write8(IPC_FAIL); + else + { + delete new_connection; + // and fall through to delete everything else + } } } + + // Something went wrong, send failure message and delete everything + codeco->Write8(IPC_FAIL); + + delete codeco; + delete codeci; + delete stream; + sock->Destroy(); } +// -------------------------------------------------------------------------- +// wxTCPEventHandlerModule (private class) +// -------------------------------------------------------------------------- + +class WXDLLEXPORT wxTCPEventHandlerModule: public wxModule +{ + DECLARE_DYNAMIC_CLASS(wxTCPEventHandlerModule) + +public: + bool OnInit() { gs_handler = new wxTCPEventHandler(); return TRUE; } + void OnExit() { wxDELETE(gs_handler); } +}; + +IMPLEMENT_DYNAMIC_CLASS(wxTCPEventHandlerModule, wxModule) + + #endif - // wxUSE_SOCKETS + // wxUSE_SOCKETS && wxUSE_IPC