bool RPC1::CallBlocking( OVR::String uniqueID, OVR::Net::BitStream* bitStream, Ptr<Connection> pConnection, OVR::Net::BitStream* returnData ) { // If invalid parameters, if (!pConnection) { // Note: This may happen if the endpoint disconnects just before the call return false; } OVR::Net::BitStream out; out.Write((MessageID) OVRID_RPC1); out.Write((MessageID) CALL_BLOCKING); out.Write(uniqueID); if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } SendParameters sp(pConnection, out.GetData(), out.GetNumberOfBytesUsed()); if (returnData) { returnData->Reset(); } // Only one thread call at a time Lock::Locker singleRPCLocker(&singleRPCLock); // Note this does not prevent multiple calls at a time because .Wait will unlock it below. // The purpose of this mutex is to synchronize the polling thread and this one, not prevent // multiple threads from invoking RPC. Mutex::Locker locker(&callBlockingMutex); blockingReturnValue->Reset(); blockingOnThisConnection = pConnection; int bytesSent = pSession->Send(&sp); if (bytesSent == sp.Bytes) { while (blockingOnThisConnection == pConnection) { callBlockingWait.Wait(&callBlockingMutex); } } if (returnData) { returnData->Write(blockingReturnValue); returnData->ResetReadPointer(); } return true; }
void RPC1::BroadcastSignal(OVR::String sharedIdentifier, OVR::Net::BitStream* bitStream) { OVR::Net::BitStream out; out.Write((MessageID) OVRID_RPC1); out.Write((MessageID) ID_RPC4_SIGNAL); //out.Write(PluginId); out.Write(sharedIdentifier); if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } BroadcastParameters p(out.GetData(), out.GetNumberOfBytesUsed()); pSession->Broadcast(&p); }
bool RPC1::Signal(OVR::String sharedIdentifier, OVR::Net::BitStream* bitStream, Ptr<Connection> pConnection) { OVR::Net::BitStream out; out.Write((MessageID) OVRID_RPC1); out.Write((MessageID) ID_RPC4_SIGNAL); //out.Write(PluginId); out.Write(sharedIdentifier); if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } SendParameters sp(pConnection, out.GetData(), out.GetNumberOfBytesUsed()); int32_t bytesSent = pSession->Send(&sp); return bytesSent == sp.Bytes; }
void RPC1::OnReceive(ReceivePayload *pPayload, ListenerReceiveResult *lrrOut) { OVR_UNUSED(lrrOut); if (pPayload->pData[0] == OVRID_RPC1) { OVR_ASSERT(pPayload->Bytes >= 2); OVR::Net::BitStream bsIn((char*)pPayload->pData, pPayload->Bytes, false); bsIn.IgnoreBytes(2); if (pPayload->pData[1] == RPC_ERROR_FUNCTION_NOT_REGISTERED) { Mutex::Locker locker(&callBlockingMutex); blockingReturnValue->Reset(); blockingOnThisConnection = 0; callBlockingWait.NotifyAll(); } else if (pPayload->pData[1] == ID_RPC4_RETURN) { Mutex::Locker locker(&callBlockingMutex); blockingReturnValue->Reset(); blockingReturnValue->Write(bsIn); blockingOnThisConnection = 0; callBlockingWait.NotifyAll(); } else if (pPayload->pData[1] == CALL_BLOCKING) { OVR::String uniqueId; bsIn.Read(uniqueId); RPCDelegate *bf = registeredBlockingFunctions.Get(uniqueId); if (bf==0) { OVR::Net::BitStream bsOut; bsOut.Write((unsigned char) OVRID_RPC1); bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED); SendParameters sp(pPayload->pConnection, bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); pSession->Send(&sp); return; } OVR::Net::BitStream returnData; bsIn.AlignReadToByteBoundary(); (*bf)(&bsIn, &returnData, pPayload); OVR::Net::BitStream out; out.Write((MessageID) OVRID_RPC1); out.Write((MessageID) ID_RPC4_RETURN); returnData.ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(returnData); SendParameters sp(pPayload->pConnection, out.GetData(), out.GetNumberOfBytesUsed()); pSession->Send(&sp); } else if (pPayload->pData[1]==ID_RPC4_SIGNAL) { OVR::String sharedIdentifier; bsIn.Read(sharedIdentifier); Observer<RPCSlot> *o = slotHash.GetSubject(sharedIdentifier); if (o) { bsIn.AlignReadToByteBoundary(); if (o) { OVR::Net::BitStream serializedParameters(bsIn.GetData() + bsIn.GetReadOffset()/8, bsIn.GetNumberOfUnreadBits()/8, false); o->Call(&serializedParameters, pPayload); } } } } }