예제 #1
0
        protected void OnNewWorkerAvailable(WorkerProcess worker)
        {
            lock (this.workers)
            {
                worker.Queue = this;
                workers.Add(worker);

                // offload draining the IO queues to this new worker on a different thread
                ActionItem.Schedule(dispatchToNewWorkerCallback, worker);
            }
        }
예제 #2
0
        internal virtual void Unregister(WorkerProcess worker)
        {
            Debug.Print("MessageQueue.Unregister() worker: " + worker.ProcessId);
            lock (registry)
            {
                Fx.Assert(object.Equals(this, worker.Queue), "MessageQueue.Unregister() cannot unregister a worker registered with a queue different than this.");

                workers.Remove(worker);
                Debug.Print("MessageQueue.Unregister() left with workers: " + workers.Count);
                if (workers.Count == 0)
                {
                    OnUnregisterLastWorker();
                }
            }
        }
예제 #3
0
        internal static ListenerExceptionStatus Register(BaseUriWithWildcard path, WorkerProcess worker)
        {
            MessageQueue queue = null;

            lock (registry)
            {
                if (registry.TryGetValue(path, out queue))
                {
                    if (!queue.CanShare)
                    {
                        return(ListenerExceptionStatus.ConflictingRegistration);
                    }
                }
                else
                {
                    queue = new MessageQueue();
                    ListenerExceptionStatus status = ListenerExceptionStatus.FailedToListen;

                    try
                    {
                        status = queue.Register(path);
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            throw;
                        }

                        if (DiagnosticUtility.ShouldTraceError)
                        {
                            ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.RoutingTableCannotListen, SR.GetString(SR.TraceCodeRoutingTableCannotListen), new StringTraceRecord("Path", path.ToString()), null, exception);
                        }
                    }

                    if (status != ListenerExceptionStatus.Success)
                    {
                        // not setting the worker.queue is not a problem, since we can't use this WorkerProcess
                        return(status);
                    }

                    registry.Add(path, queue);
                }
            }

            queue.OnNewWorkerAvailable(worker);
            return(ListenerExceptionStatus.Success);
        }
예제 #4
0
        void EnqueueWorkerAndDispatch(WorkerProcess worker, bool canDispatchOnThisThread)
        {
            lock (SessionLock)
            {
                sessionWorkers.Enqueue(worker);
            }

            if (canDispatchOnThisThread)
            {
                DispatchSession();
            }
            else
            {
                ActionItem.Schedule(dispatchSessionCallback, this);
            }
        }
예제 #5
0
        void DispatchSession()
        {
            for (;;)
            {
                ListenerSessionConnection session = null;
                lock (SessionLock)
                {
                    if (sessionMessages.Count > 0)
                    {
                        WorkerProcess worker = null;
                        while (sessionWorkers.Count > 0)
                        {
                            worker = sessionWorkers.Dequeue();
                            if (worker.IsRegistered)
                            {
                                break;
                            }
                            worker = null;
                        }

                        if (worker == null)
                        {
                            // There is no more active worker. So break the loop.
                            break;
                        }

                        // For better performance, we may want to check whether the message has been timed out in the future.
                        session = sessionMessages.Dequeue();
                        session.WorkerProcess = worker;
                    }
                }

                if (session == null)
                {
                    // There is mo more message left. So break the loop.
                    break;
                }

                StartDispatchSession(session);
            }
        }
예제 #6
0
        static void DispatchToNewWorkerCallback(object state)
        {
            WorkerProcess worker = state as WorkerProcess;

            worker.Queue.EnqueueWorkerAndDispatch(worker, true);
        }
예제 #7
0
        internal static ListenerExceptionStatus Register(int listenerChannelId, Guid token, WorkerProcess worker)
        {
            Debug.Print("ActivatedMessageQueue.Register() listenerChannelId: " + listenerChannelId + " token: " + token + " worker: " + worker.ProcessId);
            
            ActivatedMessageQueue thisPtr = null;
            lock (listenerChannelIds)
            {
                thisPtr = Find(listenerChannelId);
                if (thisPtr == null)
                {
                    // this is an error.
                    return ListenerExceptionStatus.InvalidArgument;
                }

                if (!token.Equals(thisPtr.listenerChannelContext.Token))
                {
                    return ListenerExceptionStatus.InvalidArgument;
                }
            }

            thisPtr.OnListenerChannelConnected();
            thisPtr.OnNewWorkerAvailable(worker);
            return ListenerExceptionStatus.Success;
        }
예제 #8
0
        internal virtual void Unregister(WorkerProcess worker)
        {
            Debug.Print("MessageQueue.Unregister() worker: " + worker.ProcessId);
            lock (registry)
            {
                Fx.Assert(object.Equals(this, worker.Queue), "MessageQueue.Unregister() cannot unregister a worker registered with a queue different than this.");

                workers.Remove(worker);
                Debug.Print("MessageQueue.Unregister() left with workers: " + workers.Count);
                if (workers.Count == 0)
                {
                    OnUnregisterLastWorker();
                }
            }
        }
예제 #9
0
        internal static ListenerExceptionStatus Register(BaseUriWithWildcard path, WorkerProcess worker)
        {
            MessageQueue queue = null;
            lock (registry)
            {
                if (registry.TryGetValue(path, out queue))
                {
                    if (!queue.CanShare)
                    {
                        return ListenerExceptionStatus.ConflictingRegistration;
                    }
                }
                else
                {
                    queue = new MessageQueue();
                    ListenerExceptionStatus status = ListenerExceptionStatus.FailedToListen;

                    try
                    {
                        status = queue.Register(path);
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            throw;
                        }

                        if (DiagnosticUtility.ShouldTraceError)
                        {
                            ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.RoutingTableCannotListen, SR.GetString(SR.TraceCodeRoutingTableCannotListen), new StringTraceRecord("Path", path.ToString()), null, exception);
                        }
                    }

                    if (status != ListenerExceptionStatus.Success)
                    {
                        // not setting the worker.queue is not a problem, since we can't use this WorkerProcess
                        return status;
                    }

                    registry.Add(path, queue);
                }
            }

            queue.OnNewWorkerAvailable(worker);
            return ListenerExceptionStatus.Success;
        }
예제 #10
0
        protected void OnNewWorkerAvailable(WorkerProcess worker)
        {
            lock (this.workers)
            {
                worker.Queue = this;
                workers.Add(worker);

                // offload draining the IO queues to this new worker on a different thread
                ActionItem.Schedule(dispatchToNewWorkerCallback, worker);
            }
        }
예제 #11
0
        void EnqueueWorkerAndDispatch(WorkerProcess worker, bool canDispatchOnThisThread)
        {
            lock (SessionLock)
            {
                sessionWorkers.Enqueue(worker);
            }

            if (canDispatchOnThisThread)
            {
                DispatchSession();
            }
            else
            {
                ActionItem.Schedule(dispatchSessionCallback, this);
            }
        }
예제 #12
0
        internal static ListenerExceptionStatus Register(int listenerChannelId, Guid token, WorkerProcess worker)
        {
            Debug.Print("ActivatedMessageQueue.Register() listenerChannelId: " + listenerChannelId + " token: " + token + " worker: " + worker.ProcessId);

            ActivatedMessageQueue thisPtr = null;

            lock (listenerChannelIds)
            {
                thisPtr = Find(listenerChannelId);
                if (thisPtr == null)
                {
                    // this is an error.
                    return(ListenerExceptionStatus.InvalidArgument);
                }

                if (!token.Equals(thisPtr.listenerChannelContext.Token))
                {
                    return(ListenerExceptionStatus.InvalidArgument);
                }
            }

            thisPtr.OnListenerChannelConnected();
            thisPtr.OnNewWorkerAvailable(worker);
            return(ListenerExceptionStatus.Success);
        }