internal void SendRequestAndWait(RemoteCall rc) { Debug.Assert(!rc.returnImmediately); lock (rc) { if (ShuttingDown || connectionLostException != null) { return; } newCalls.Add(rc); Write(rc.WriteRequest); Monitor.Wait(rc); } while (rc.nextCall != null) { var nextCall = rc.nextCall; rc.nextCall = null; nextCall.Execute(this); lock (rc) { if (!nextCall.returnImmediately) { Write(nextCall.WriteResponse); } Monitor.Wait(rc); } } }
internal void Push(RemoteCall call) { lock(stacks) { Stack<RemoteCall> stack; if(!stacks.TryGetValue(call.localThreadId, out stack)) { stack = new Stack<RemoteCall>(); stacks.Add(call.localThreadId, stack); } stack.Push(call); } }
internal void Push(RemoteCall call) { lock (stacks) { Stack <RemoteCall> stack; if (!stacks.TryGetValue(call.localThreadId, out stack)) { stack = new Stack <RemoteCall>(); stacks.Add(call.localThreadId, stack); } stack.Push(call); } }
internal void RequestExecution(RemoteConnection connection) { if (CfxRemoteCallContext.IsInContext && CfxRemoteCallContext.CurrentContext.connection != connection) { // The thread is in a remote call context, but the requestor wants to call // on another connection. This can happen if a CfrObject method from one connection // is used within the scope of a callback from another connection. // In this case, the call has to be made in a temporary context with remote thread id zero. var ctx = new CfxRemoteCallContext(connection, 0); ctx.Enter(); try { RequestExecution(connection); } finally { ctx.Exit(); } return; } if (returnImmediately) { if (connection.ShuttingDown) { return; } else if (connection.connectionLostException != null) { throw new CfxRemotingException("Remote connection lost.", connection.connectionLostException); } connection.Write(WriteRequest); return; } lock (waitLock) { // The lock must begin here. Otherwise, // there is a race between Wait and PulseAll // causing this thread to wait forever // under some circumstances. localThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; connection.callStack.Push(this); remoteThreadId = CfxRemoteCallContext.currentThreadId; connection.Write(WriteRequest); for (; ;) { if (responseReceived) { Debug.Assert(reentryCall == null); return; } if (this.reentryCall != null) { reentryCall.ExecutionThreadEntry(connection); reentryCall = null; } if (!connection.ShuttingDown && connection.connectionLostException == null) { System.Threading.Monitor.Wait(waitLock); } if (connection.ShuttingDown) { return; } else if (connection.connectionLostException != null) { if (RemoteClient.connection != null) { // this is the render process calling back into the browser process // reaching this point usually means the browser process crashed or was killed // don't throw, just return so the process can exit gracefully return; } throw new CfxRemotingException("Remote connection lost.", connection.connectionLostException); } } } }
internal void RequestExecution(RemoteConnection connection) { if(CfxRemoteCallContext.IsInContext && CfxRemoteCallContext.CurrentContext.connection != connection) { // The thread is in a remote call context, but the requestor wants to call // on another connection. This can happen if a CfrObject method from one connection // is used within the scope of a callback from another connection. // In this case, the call has to be made in a temporary context with remote thread id zero. var ctx = new CfxRemoteCallContext(connection, 0); ctx.Enter(); try { RequestExecution(connection); } finally { ctx.Exit(); } return; } if(returnImmediately) { if(connection.ShuttingDown) return; else if(connection.connectionLostException != null) throw new CfxRemotingException("Remote connection lost.", connection.connectionLostException); connection.EnqueueWrite(WriteRequest); return; } lock(waitLock) { // The lock must begin here. Otherwise, // there is a race between Wait and PulseAll // causing this thread to wait forever // under some circumstances. localThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; connection.callStack.Push(this); remoteThreadId = CfxRemoteCallContext.currentThreadId; connection.EnqueueWrite(WriteRequest); for(; ; ) { if(responseReceived) { Debug.Assert(reentryCall == null); return; } if(this.reentryCall != null) { reentryCall.ExecutionThreadEntry(connection); reentryCall = null; } if(!connection.ShuttingDown && connection.connectionLostException == null) System.Threading.Monitor.Wait(waitLock); if(connection.ShuttingDown) return; else if(connection.connectionLostException != null) { if(RemoteClient.connection != null) { // this is the render process calling back into the browser process // reaching this point usually means the browser process crashed or was killed // don't throw, just return so the process can exit gracefully return; } throw new CfxRemotingException("Remote connection lost.", connection.connectionLostException); } } } }