void P_SEND_Timer_IMPL(PRT_MACHINEINST *context, PRT_VALUE *evnt, PRT_VALUE *payload, PRT_BOOLEAN doTransfer) { printf("Entering P_SEND_Timer_IMPL\n"); PRT_VALUE *ev; BOOL success; TimerContext *timerContext = (TimerContext *)context->extContext; if (!inStart && evnt->valueUnion.ev == P_EVENT_START) { printf("Timer received START\n"); LARGE_INTEGER liDueTime; liDueTime.QuadPart = -10000 * payload->valueUnion.nt; success = SetWaitableTimer(timerContext->timer, &liDueTime, 0, Callback, context, FALSE); inStart = TRUE; PrtAssert(success, "SetWaitableTimer failed"); } else if (evnt->valueUnion.ev == P_EVENT_CANCEL) { printf("Timer received CANCEL\n"); inStart = FALSE; success = CancelWaitableTimer(timerContext->timer); if (success) { ev = PrtMkEventValue(P_EVENT_CANCEL_SUCCESS); PrtSend(context, PrtGetMachine(context->process, timerContext->client), ev, context->id, PRT_FALSE); } else { ev = PrtMkEventValue(P_EVENT_CANCEL_FAILURE); PrtSend(context, PrtGetMachine(context->process, timerContext->client), ev, context->id, PRT_FALSE); } PrtFreeValue(ev); } else { PrtAssert(FALSE, "Illegal event"); } }
PRT_VALUE *P_FUN_StartTimer_IMPL(PRT_MACHINEINST *context) { PRT_MACHINEINST_PRIV *p_tmp_mach_priv = (PRT_MACHINEINST_PRIV *)context; PRT_VALUE *p_tmp_ret = NULL; PRT_FUNSTACK_INFO p_tmp_frame; // pop frame PrtPopFrame(p_tmp_mach_priv, &p_tmp_frame); PRT_VALUE* timerMachineId = p_tmp_frame.locals[0]; PRT_MACHINEINST* timerMachine = PrtGetMachine(context->process, timerMachineId); TimerContext *timerContext = (TimerContext *)timerMachine->extContext; int timeout_value = p_tmp_frame.locals[1]->valueUnion.nt; SleepMs(timeout_value); PRT_VALUE *ev = PrtMkEventValue(P_EVENT_TIMEOUT); PRT_MACHINEINST* clientMachine = PrtGetMachine(context->process, timerContext->client); PrtSend(context, clientMachine, ev, context->id, PRT_FALSE); PrtFreeValue(ev); // free the frame PrtFreeLocals(p_tmp_mach_priv, &p_tmp_frame); return NULL; }
VOID CALLBACK Callback(LPVOID arg, DWORD dwTimerLowValue, DWORD dwTimerHighValue) { inStart = FALSE; PRT_MACHINEINST *context = (PRT_MACHINEINST *)arg; TimerContext *timerContext = (TimerContext *)context->extContext; PRT_VALUE *ev = PrtMkEventValue(P_EVENT_TIMEOUT); PrtSend(PrtGetMachine(context->process, timerContext->client), ev, context->id, PRT_FALSE); PrtFreeValue(ev); }
// Function for enqueueing message into the remote machine void s_PrtDistSendEx( PRPC_ASYNC_STATE asyncState, handle_t handle, PRT_VALUE* target, PRT_VALUE* event, PRT_VALUE* payload ) { //get the context handle for this function PRT_VALUE* deserial_target = PrtDistDeserializeValue(target); PRT_VALUE* deserial_event = PrtDistDeserializeValue(event); PRT_VALUE* deserial_payload = PrtDistDeserializeValue(payload); PRT_MACHINEINST* context = PrtGetMachine(ContainerProcess, deserial_target); PrtSend(context, deserial_event, deserial_payload); }