internal bool RunSingleEventLoopIteration() { if (this.IsEventLoopAlive) { EventLoopInvocation invocation = PopItemFromQueue(); if (invocation != null) { RunEventLoopIteration(invocation); return(true); } } return(false); }
private void AddItemToQueue(EventLoopInvocation invocation) { lock (this.state) { if (!this.state.IsStillRunning) { return; } this.state.Queue.Enqueue(invocation); } lock (this.wakeupTaskMutex) { if (this.wakeupTask != null) // Root execution context starting will not have a wakup task to trigger { this.wakeupTask.TrySetResult(true); } } }
private void RunEventLoopIteration(EventLoopInvocation invocation) { // Debugger.INSTANCE.FlushMessageQueue(); if (invocation == null) { return; } InterpreterResult result; if (invocation.StartFromBeginning) { result = CrayonWrapper.startVm(vm); } else if (invocation.FunctionPointer != null) { Value[] args = invocation.FunctionPointerArgs; if (args == null) { object[] nativeArgs = invocation.FunctionPointerNativeArgs; args = new Value[nativeArgs.Length]; for (int i = 0; i < args.Length; ++i) { args[i] = ConvertNativeArg(nativeArgs[i]); } } result = CrayonWrapper.runInterpreterWithFunctionPointer(vm, invocation.FunctionPointer, args); } else { result = CrayonWrapper.runInterpreter(vm, invocation.ExecutionContextId); } switch (result.status) { case 1: // execution context is FINISHED if (result.isRootContext) { this.KillEventLoop(); } break; case 2: // SUSPEND // do nothing. break; case 3: // FATAL ERROR if (result.isRootContext) { this.KillEventLoop(); } break; case 5: // RE-INVOKE, possibly with a delay ResumeExecutionAfterDelay(result.executionContextId, result.reinvokeDelay); break; case 7: // BREAKPOINT // do nothing break; } if (!this.IsEventLoopAlive && this.completionCallback != null) { this.completionCallback(); this.completionCallback = null; } }