From 3d944a3f2db75f9f706d92b03dcfe8dbef9910f4 Mon Sep 17 00:00:00 2001 From: JP Mattia Date: Thu, 3 Oct 2024 11:36:39 -0700 Subject: [PATCH] FindMessage is used when a reply is expected for a sent message. As an example, IPC_REQUEST from the client expects the specific reply of IPC_REQUEST_REPLY. It is possible that the server sneaks in other messages, such as a stream of IPC_ADVISE data. So FindMessage loops until the desired message is found, executing any other unexpected messages that happen to be read first. --- src/common/sckipc.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/common/sckipc.cpp b/src/common/sckipc.cpp index ae13ba6f35..890571bd9d 100644 --- a/src/common/sckipc.cpp +++ b/src/common/sckipc.cpp @@ -137,6 +137,10 @@ public: void Server_OnRequest(wxSocketEvent& event); bool ExecuteMessage(wxIPCMessageBase* msg, wxSocketBase *socket); + bool FindMessage(IPCCode code, + wxSocketBase* socket, + wxIPCMessageBase** msgptr); + void SendFailMessage(const wxString& reason, wxSocketBase* socket); void HandleDisconnect(wxTCPConnection *connection); @@ -1490,14 +1494,50 @@ bool wxTCPEventHandler::ExecuteMessage(wxIPCMessageBase* msg, wxSocketBase *sock return true; } +// Find a message with IPCCode code. Returns true when a valid message with +// the matching IPCCode is found. If msgptr is non-null, then the message is +// also returned and the caller is responsible for deleting the returned +// message. +bool wxTCPEventHandler::FindMessage(IPCCode code, + wxSocketBase* socket, + wxIPCMessageBase** return_msgptr) +{ + while ( GetConnection(socket) ) { + wxIPCMessageBase* msg = ReadMessageFromSocket(socket); + if ( msg && msg->GetIPCCode() == code ) { + // The correct message has been found, but there may still be + // messages waiting in the socket data buffer. Place an event in + // the socket event queue so that they will be read out later. + if (socket && socket->GetEventHandler()) { + wxSocketEvent event(wxID_ANY); + event.m_event = wxSOCKET_INPUT; + event.m_clientData = socket->GetClientData(); + event.SetEventObject(socket); + + socket->GetEventHandler()->AddPendingEvent(event); } + + if (return_msgptr) + *return_msgptr = msg; + else + delete msg; + + return true; } + // Not the correct msg to be returned. + wxIPCMessageBaseLocker lock(msg); + if (!ExecuteMessage(msg, socket) ) + return false; + }; + + return false; +} // Reads a single message from the socket. Returns wxIPCMessageNull when no // message was read. The returned message must be freed by the caller.