IIPCChannel* gIPCChannel;
::std::mutex glSyncReply;
+bool gSyncReplyActive;
bool gSyncReplyValid;
CDeserialiser gSyncReplyBuf;
void RecvMessage(CDeserialiser& message)
{
uint8_t id = message.ReadU8();
+ _SysDebug("RecvMessage: id=%i", id);
switch(id)
{
+ case IPCMSG_PING:
+ // If we hear ping, we must pong
+ {
+ CSerialiser pong;
+ pong.WriteU8(IPCMSG_REPLY);
+ pong.WriteU8(IPCMSG_PING);
+ SendMessage(pong);
+ }
+ break;
case IPCMSG_REPLY:
// Flag reply and take a copy of this message
- if( gSyncReplyValid )
+ if( !gSyncReplyActive )
+ {
+ _SysDebug("Unexpected reply message %i", message.ReadU8());
+ }
+ else if( gSyncReplyValid )
{
// Oh... that was unexpected
_SysDebug("Unexpected second reply message %i", message.ReadU8());
gSyncReplyBuf = message;
}
break;
+ // TODO: Handle messages from server (input events, IPC)
+ // TODO: If an event is currently being processed, save the message in a queue to be handled when processing is complete
+ // - This will prevent deep recursion (and make server errors aparent)
default:
_SysDebug("TODO: RecvMessage(%i)", id);
break;
CDeserialiser GetSyncReply(CSerialiser& request, unsigned int Message)
{
::std::lock_guard<std::mutex> lock(glSyncReply);
+ gSyncReplyActive = true;
gSyncReplyValid = false;
// Send once lock is acquired
SendMessage(request);
if( !AxWin4_WaitEventQueue(0) )
throw ::std::runtime_error("Connection dropped while waiting for reply");
}
+ gSyncReplyActive = false;
uint8_t id = gSyncReplyBuf.ReadU8();
if( id != Message )
{
- _SysDebug("Unexpected reply message '%i', message.ReadU8()");
+ _SysDebug("Unexpected reply message id=%i, expected %i",
+ id, Message);
+ throw ::std::runtime_error("Sequencing error, unexpected reply");
}
- return gSyncReplyBuf;
+ // Use move to avoid copying
+ return ::std::move(gSyncReplyBuf);
}
extern "C" void AxWin4_GetScreenDimensions(unsigned int ScreenIndex, unsigned int *Width, unsigned int *Height)