X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/22a9029e2306865655c8f9f36383929fc6381ea9..b53aea81d2e102224b452ef5bf7aee1132f37c6f:/src/common/sckipc.cpp diff --git a/src/common/sckipc.cpp b/src/common/sckipc.cpp index 50dcb26fef..0aed548807 100644 --- a/src/common/sckipc.cpp +++ b/src/common/sckipc.cpp @@ -53,20 +53,22 @@ namespace { -// Message codes +// Message codes (don't change them to avoid breaking the existing code using +// wxIPC protocol!) enum IPCCode { - IPC_EXECUTE = 1, - IPC_REQUEST, - IPC_POKE, - IPC_ADVISE_START, - IPC_ADVISE_REQUEST, - IPC_ADVISE, - IPC_ADVISE_STOP, - IPC_REQUEST_REPLY, - IPC_FAIL, - IPC_CONNECT, - IPC_DISCONNECT + IPC_EXECUTE = 1, + IPC_REQUEST = 2, + IPC_POKE = 3, + IPC_ADVISE_START = 4, + IPC_ADVISE_REQUEST = 5, + IPC_ADVISE = 6, + IPC_ADVISE_STOP = 7, + IPC_REQUEST_REPLY = 8, + IPC_FAIL = 9, + IPC_CONNECT = 10, + IPC_DISCONNECT = 11, + IPC_MAX }; } // anonymous namespace @@ -117,11 +119,12 @@ GetAddressFromName(const wxString& serverName, class wxTCPEventHandler : public wxEvtHandler { public: - wxTCPEventHandler() : wxEvtHandler() {} + wxTCPEventHandler() : wxEvtHandler() { } void Client_OnRequest(wxSocketEvent& event); void Server_OnRequest(wxSocketEvent& event); +private: DECLARE_EVENT_TABLE() DECLARE_NO_COPY_CLASS(wxTCPEventHandler) }; @@ -132,7 +135,38 @@ enum _SERVER_ONREQUEST_ID }; -static wxTCPEventHandler *gs_handler = NULL; +// -------------------------------------------------------------------------- +// wxTCPEventHandlerModule (private class) +// -------------------------------------------------------------------------- + +class wxTCPEventHandlerModule : public wxModule +{ +public: + wxTCPEventHandlerModule() : wxModule() { } + + // get the global wxTCPEventHandler creating it if necessary + static wxTCPEventHandler& GetHandler() + { + if ( !ms_handler ) + ms_handler = new wxTCPEventHandler; + + return *ms_handler; + } + + // as ms_handler is initialized on demand, don't do anything in OnInit() + virtual bool OnInit() { return true; } + virtual void OnExit() { wxDELETE(ms_handler); } + +private: + static wxTCPEventHandler *ms_handler; + + DECLARE_DYNAMIC_CLASS(wxTCPEventHandlerModule) + DECLARE_NO_COPY_CLASS(wxTCPEventHandlerModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxTCPEventHandlerModule, wxModule) + +wxTCPEventHandler *wxTCPEventHandlerModule::ms_handler = NULL; // -------------------------------------------------------------------------- // wxIPCSocketStreams @@ -150,11 +184,11 @@ public: // ctor initializes all the streams on top of the given socket // // note that we use a bigger than default buffer size which matches the - // typical Ethernet MTU + // typical Ethernet MTU (minus TCP header overhead) wxIPCSocketStreams(wxSocketBase& sock) : m_socketStream(sock), #ifdef USE_BUFFER - m_bufferedOut(m_socketStream, 1500), + m_bufferedOut(m_socketStream, 1448), #else m_bufferedOut(m_socketStream), #endif @@ -368,7 +402,8 @@ wxConnectionBase *wxTCPClient::MakeConnection(const wxString& host, connection->m_topic = topic; connection->m_sock = client; connection->m_streams = streams; - client->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID); + client->SetEventHandler(wxTCPEventHandlerModule::GetHandler(), + _CLIENT_ONREQUEST_ID); client->SetClientData(connection); client->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG); client->Notify(true); @@ -469,7 +504,8 @@ bool wxTCPServer::Create(const wxString& serverName) return false; } - m_server->SetEventHandler(*gs_handler, _SERVER_ONREQUEST_ID); + m_server->SetEventHandler(wxTCPEventHandlerModule::GetHandler(), + _SERVER_ONREQUEST_ID); m_server->SetClientData(this); m_server->SetNotify(wxSOCKET_CONNECTION_FLAG); m_server->Notify(true); @@ -576,11 +612,15 @@ const void *wxTCPConnection::Request(const wxString& item, IPCOutput(m_streams).Write(IPC_REQUEST, item, format); - int ret = m_streams->Read8(); - if ( ret == IPC_FAIL ) + const int ret = m_streams->Read8(); + if ( ret != IPC_REQUEST_REPLY ) return NULL; - return m_streams->ReadData(this, size); + // ReadData() needs a non-NULL size pointer but the client code can call us + // with NULL pointer (this makes sense if it knows that it always works + // with NUL-terminated strings) + size_t sizeFallback; + return m_streams->ReadData(this, size ? size : &sizeFallback); } bool wxTCPConnection::DoPoke(const wxString& item, @@ -605,11 +645,9 @@ bool wxTCPConnection::StartAdvise(const wxString& item) IPCOutput(m_streams).Write(IPC_ADVISE_START, item); - int ret = m_streams->Read8(); - if (ret != IPC_FAIL) - return true; - else - return false; + const int ret = m_streams->Read8(); + + return ret == IPC_ADVISE_START; } bool wxTCPConnection::StopAdvise (const wxString& item) @@ -619,12 +657,9 @@ bool wxTCPConnection::StopAdvise (const wxString& item) IPCOutput(m_streams).Write(IPC_ADVISE_STOP, item); - int ret = m_streams->Read8(); + const int ret = m_streams->Read8(); - if (ret != IPC_FAIL) - return true; - else - return false; + return ret == IPC_ADVISE_STOP; } // Calls that SERVER can make @@ -680,17 +715,21 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event) const wxString topic = connection->m_topic; wxString item; + bool error = false; + const int msg = streams->Read8(); switch ( msg ) { case IPC_EXECUTE: { wxIPCFormat format; - size_t size; + size_t size wxDUMMY_INITIALIZE(0); void * const data = streams->ReadFormatData(connection, &format, &size); - - connection->OnExecute(topic, data, size, format); + if ( data ) + connection->OnExecute(topic, data, size, format); + else + error = true; } break; @@ -699,11 +738,14 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event) item = streams->ReadString(); wxIPCFormat format; - size_t size; + size_t size wxDUMMY_INITIALIZE(0); void * const data = streams->ReadFormatData(connection, &format, &size); - connection->OnAdvise(topic, item, data, size, format); + if ( data ) + connection->OnAdvise(topic, item, data, size, format); + else + error = true; } break; @@ -732,10 +774,13 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event) item = streams->ReadString(); wxIPCFormat format = (wxIPCFormat)streams->Read8(); - size_t size; + size_t size wxDUMMY_INITIALIZE(0); void * const data = streams->ReadData(connection, &size); - connection->OnPoke(topic, item, data, size, format); + if ( data ) + connection->OnPoke(topic, item, data, size, format); + else + error = true; } break; @@ -787,11 +832,19 @@ void wxTCPEventHandler::Client_OnRequest(wxSocketEvent &event) connection->OnDisconnect(); break; + case IPC_FAIL: + wxLogDebug("Unexpected IPC_FAIL received"); + error = true; + break; + default: wxLogDebug("Unknown message code %d received.", msg); - IPCOutput(streams).Write8(IPC_FAIL); + error = true; break; } + + if ( error ) + IPCOutput(streams).Write8(IPC_FAIL); } void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event) @@ -841,7 +894,8 @@ void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event) new_connection->m_sock = sock; new_connection->m_streams = streams; new_connection->m_topic = topic; - sock->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID); + sock->SetEventHandler(wxTCPEventHandlerModule::GetHandler(), + _CLIENT_ONREQUEST_ID); sock->SetClientData(new_connection); sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG); sock->Notify(true); @@ -863,19 +917,4 @@ void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event) sock->Destroy(); } -// -------------------------------------------------------------------------- -// wxTCPEventHandlerModule (private class) -// -------------------------------------------------------------------------- - -class wxTCPEventHandlerModule: public wxModule -{ -public: - virtual bool OnInit() { gs_handler = new wxTCPEventHandler; return true; } - virtual void OnExit() { wxDELETE(gs_handler); } - - DECLARE_DYNAMIC_CLASS(wxTCPEventHandlerModule) -}; - -IMPLEMENT_DYNAMIC_CLASS(wxTCPEventHandlerModule, wxModule) - #endif // wxUSE_SOCKETS && wxUSE_IPC && wxUSE_STREAMS