private void ExecutionThreadEntry(RemoteConnection connection) { if (returnImmediately) { // only happens in calls from the browser to the renderer CfxDebug.Assert(connection == RemoteClient.connection); ExecuteInTargetProcess(connection); return; } if (RemoteClient.connection == null) { if (!CfxRemoteCallbackManager.IncrementCallbackCount(connection.remoteProcessId)) { // The application has suspended remote callbacks. // Write the response without ececuting event handlers, returning default values. connection.EnqueueWrite(WriteResponse); return; } } var threadContext = new CfxRemoteCallContext(connection, remoteThreadId); threadContext.Enter(); var threadStackCount = CfxRemoteCallContext.ContextStackCount; try { ExecuteInTargetProcess(connection); } finally { if (RemoteClient.connection == null) { CfxRemoteCallbackManager.DecrementCallbackCount(connection.remoteProcessId); } if (threadStackCount != CfxRemoteCallContext.ContextStackCount || CfxRemoteCallContext.CurrentContext != threadContext) { CfxRemoteCallContext.resetStack(threadStackCount - 1); throw new CfxException("Unbalanced remote call context stack. Make sure to balance calls to CfxRemoteCallContext.Enter() and CfxRemoteCallContext.Exit() in all render process callback events."); } threadContext.Exit(); } connection.EnqueueWrite(WriteResponse); }
internal void RequestExecution(RemoteConnection connection) { if (returnImmediately) { connection.Write(WriteRequest); return; } 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; } localThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; remoteThreadId = CfxRemoteCallContext.currentThreadId; connection.SendRequestAndWait(this); 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 exception in the browser process throw new CfxRemotingException("Remote connection lost.", connection.connectionLostException); } }
/// <summary> /// Prepares and executes the remote procedure in the remote process /// </summary> internal void Execute(RemoteConnection connection) { if (returnImmediately) { RemoteProcedure(); return; } if (RemoteClient.connection == null) { if (!CfxRemoteCallbackManager.IncrementCallbackCount(connection.remoteProcessId)) { // The application has suspended remote callbacks. // Return without ececuting event handlers, connection will return default values. return; } } var threadContext = new CfxRemoteCallContext(connection, remoteThreadId); threadContext.Enter(); var threadStackCount = CfxRemoteCallContext.ContextStackCount; try { RemoteProcedure(); } finally { if (RemoteClient.connection == null) { CfxRemoteCallbackManager.DecrementCallbackCount(connection.remoteProcessId); } if (threadStackCount != CfxRemoteCallContext.ContextStackCount || CfxRemoteCallContext.CurrentContext != threadContext) { CfxRemoteCallContext.resetStack(threadStackCount - 1); throw new CfxException("Unbalanced remote call context stack. Make sure to balance calls to CfxRemoteCallContext.Enter() and CfxRemoteCallContext.Exit() in all render process callback events."); } threadContext.Exit(); } }
public void Dispose() { _CfxRemoteCallContext.Exit(); }
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); } } } }
private void ExecutionThreadEntry(RemoteConnection connection) { if(returnImmediately) { // only happens in calls from the browser to the renderer CfxDebug.Assert(connection == RemoteClient.connection); ExecuteInTargetProcess(connection); return; } if(RemoteClient.connection == null) { if(!CfxRemoteCallbackManager.IncrementCallbackCount(connection.remoteProcessId)) { // The application has suspended remote callbacks. // Write the response without ececuting event handlers, returning default values. connection.EnqueueWrite(WriteResponse); return; } } var threadContext = new CfxRemoteCallContext(connection, remoteThreadId); threadContext.Enter(); var threadStackCount = CfxRemoteCallContext.ContextStackCount; try { ExecuteInTargetProcess(connection); } finally { if(RemoteClient.connection == null) { CfxRemoteCallbackManager.DecrementCallbackCount(connection.remoteProcessId); } if(threadStackCount != CfxRemoteCallContext.ContextStackCount || CfxRemoteCallContext.CurrentContext != threadContext) { CfxRemoteCallContext.resetStack(threadStackCount - 1); throw new CfxException("Unbalanced remote call context stack. Make sure to balance calls to CfxRemoteCallContext.Enter() and CfxRemoteCallContext.Exit() in all render process callback events."); } threadContext.Exit(); } connection.EnqueueWrite(WriteResponse); }
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); } } } }