Beispiel #1
0
        /// <summary>
        /// Check if the current message will cause deadlock.
        /// Throw DeadlockException if yes.
        /// </summary>
        /// <param name="message">Message to analyze</param>
        private void CheckDeadlock(Message message)
        {
            object obj = message.GetApplicationHeader(RequestContext.CALL_CHAIN_REQUEST_CONTEXT_HEADER);

            if (obj == null)
            {
                return;              // first call in a chain
            }
            var          prevChain        = ((IList)obj);
            ActivationId nextActivationId = message.TargetActivation;

            // check if the target activation already appears in the call chain.
            foreach (object invocationObj in prevChain)
            {
                var prevId = ((RequestInvocationHistory)invocationObj).ActivationId;
                if (!prevId.Equals(nextActivationId) || catalog.IsReentrantGrain(nextActivationId))
                {
                    continue;
                }

                var newChain = new List <RequestInvocationHistory>();
                newChain.AddRange(prevChain.Cast <RequestInvocationHistory>());
                newChain.Add(new RequestInvocationHistory(message));

                throw new DeadlockException(newChain.Select(req =>
                                                            new Tuple <GrainId, int, int>(req.GrainId, req.InterfaceId, req.MethodId)).ToList());
            }
        }