Exemplo n.º 1
0
        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);
                }
            }
        }
Exemplo n.º 2
0
 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);
     }
 }
Exemplo n.º 3
0
 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);
     }
 }
Exemplo n.º 4
0
        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);
                    }
                }
            }
        }
Exemplo n.º 5
0
        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);
                    }
                }
            }
        }