Beispiel #1
0
        static ListenerExceptionStatus TcpStart(MessageQueue messageQueue, BaseUriWithWildcard path)
        {
            int encodedSize = System.Text.Encoding.UTF8.GetByteCount(path.BaseAddress.AbsoluteUri);
            if (encodedSize > ListenerConstants.MaxUriSize)
            {
                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.RoutingTablePathTooLong, SR.GetString(SR.TraceCodeRoutingTablePathTooLong), new StringTraceRecord("Path", path.ToString()), null, null);
                }

                return ListenerExceptionStatus.PathTooLong;
            }
            IPEndPoint endPoint = GetEndPoint(path.BaseAddress);
            lock (tcpMessageQueues)
            {
                if (tcpMessageQueues.IsRegistered(path))
                {
                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.RoutingTableNamespaceConflict, SR.GetString(SR.TraceCodeRoutingTableNamespaceConflict), new StringTraceRecord("Path", path.ToString()), null, null);
                    }

                    return ListenerExceptionStatus.ConflictingRegistration;
                }

                TransportListener.Listen(endPoint);
                tcpMessageQueues.RegisterUri(path.BaseAddress, path.HostNameComparisonMode, new MessageQueueAndPath(messageQueue, path.BaseAddress));
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.RoutingTableRegisterSuccess, SR.GetString(SR.TraceCodeRoutingTableRegisterSuccess), new StringTraceRecord("Path", path.ToString()), null, null);
            }

            return ListenerExceptionStatus.Success;
        }
        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;
        }
        void Unregister(BaseUriWithWildcard path)
        {
            Fx.Assert(paths.Contains(path), "Unregister: unregistering an unregistered path");

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueUnregisterSucceeded, SR.GetString(SR.TraceCodeMessageQueueUnregisterSucceeded), new StringTraceRecord("Path", path.ToString()), this, null);
            }

            if (TD.MessageQueueUnregisterSucceededIsEnabled())
            {
                TD.MessageQueueUnregisterSucceeded(this.EventTraceActivity, path.ToString());
            }

            RoutingTable.Stop(this, path);
            IncrementUrisUnregisteredCounters();
            OnUnregisterCompleted();

            registry.Remove(path);
            paths.Remove(path);
        }
Beispiel #4
0
        ListenerExceptionStatus IConnectionRegister.Register(Version version, int processId, BaseUriWithWildcard path, int queueId, Guid token, string eventName)
        {
            if (TD.MessageQueueRegisterStartIsEnabled())
            {
                TD.MessageQueueRegisterStart(this.EventTraceActivity);
            }

            Debug.Print("WorkerProcess.Register() version: " + version + " processId: " + processId + " path: " + path + " queueId: " + queueId + " token: " + token + " eventName: " + eventName);

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueRegisterCalled, SR.GetString(SR.TraceCodeMessageQueueRegisterCalled), new StringTraceRecord("Path", path.ToString()), this, null);
            }

            // Get the callback channel
            this.connectionDuplicator = OperationContext.Current.GetCallbackChannel<IConnectionDuplicator>();

            // Prevent this duplicate operation from timing out, faulting the pipe, and stopping any further communication with w3wp
            // we're gated by MaxPendingAccepts + MaxPendingConnection. see CSD Main bug 193390 for details
            ((IContextChannel)this.connectionDuplicator).OperationTimeout = TimeSpan.MaxValue;

            ListenerExceptionStatus status = ListenerExceptionStatus.Success;
            bool abortInstance = false;

            if (path == null || eventName == null)
            {
                status = ListenerExceptionStatus.InvalidArgument;
                abortInstance = true;
                goto FAILED;
            }

            // Vista only: validate remote process ID
            if (OSEnvironmentHelper.IsVistaOrGreater)
            {
                status = ListenerExceptionStatus.InvalidArgument;
                object property = OperationContext.Current.IncomingMessage.Properties[ConnectionMessageProperty.Name];
                Fx.Assert(property != null, "WorkerProcess.Register() ConnectionMessageProperty not found!");

                IConnection connection = property as IConnection;
                Fx.Assert(connection != null, "WorkerProcess.Register() ConnectionMessageProperty is not IConnection!");

                PipeHandle pipe = connection.GetCoreTransport() as PipeHandle;
                Fx.Assert(pipe != null, "WorkerProcess.Register() CoreTransport is not PipeHandle!");

                if (processId != pipe.GetClientPid())
                {
                    status = ListenerExceptionStatus.InvalidArgument;
                    abortInstance = true;
                    goto FAILED;
                }
            }

            // validate version
            Version ourVersion = Assembly.GetExecutingAssembly().GetName().Version;
            if (version > ourVersion)
            {
                // VERSIONING
                // in V1 we assume that we can handle earlier versions
                // this might not be true when we ship later releases.
                Debug.Print("WorkerProcess.Register() unsupported version ourVersion: " + ourVersion + " version: " + version);
                status = ListenerExceptionStatus.VersionUnsupported;
                goto FAILED;
            }

            if (queueId == 0 && path == null)
            {
                status = ListenerExceptionStatus.InvalidArgument;
                abortInstance = true;
                goto FAILED;
            }

            this.processId = processId;
            this.queueId = 0;
            if (queueId != 0)
            {
                this.queueId = queueId;
                status = ActivatedMessageQueue.Register(queueId, token, this);
            }
            else
            {
                status = MessageQueue.Register(path, this);
            }

            if (status == ListenerExceptionStatus.Success)
            {
                foreach (IChannel channel in OperationContext.Current.InstanceContext.IncomingChannels)
                {
                    channel.Faulted += new EventHandler(WorkerProcess_Faulted);
                    channel.Closed += new EventHandler(WorkerProcess_Closed);
                }

                try
                {
                    using (EventWaitHandle securityEvent = EventWaitHandle.OpenExisting(ListenerConstants.GlobalPrefix + eventName, EventWaitHandleRights.Modify))
                    {
                        securityEvent.Set();
                    }
                }
                catch (Exception exception)
                {
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }

                    DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error);

                    status = ListenerExceptionStatus.InvalidArgument;
                    abortInstance = true;
                }
            }

            if (status != ListenerExceptionStatus.Success)
            {
                goto FAILED;
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueRegisterSucceeded, SR.GetString(SR.TraceCodeMessageQueueRegisterSucceeded), new StringTraceRecord("Path", path.ToString()), this, null);
            }
            if (TD.MessageQueueRegisterCompletedIsEnabled())
            {
                TD.MessageQueueRegisterCompleted(this.EventTraceActivity, path.ToString());
            }
        FAILED:
            if (abortInstance)
            {
                if (DiagnosticUtility.ShouldTraceError)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.MessageQueueRegisterFailed, SR.GetString(SR.TraceCodeMessageQueueRegisterFailed),
                        new StringTraceRecord("Register", SR.GetString(SR.SharingRegistrationFailedAndAbort, status.ToString())), this, null);
                }
                if (TD.MessageQueueRegisterAbortIsEnabled())
                {
                    TD.MessageQueueRegisterAbort(this.EventTraceActivity, 
                        status.ToString(),
                        (path != null) ? path.ToString() : string.Empty);
                }

                AbortServiceInstance();
            }
            else if (status != ListenerExceptionStatus.Success)
            {
                if (DiagnosticUtility.ShouldTraceError)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.MessageQueueRegisterFailed, SR.GetString(SR.TraceCodeMessageQueueRegisterFailed),
                        new StringTraceRecord("Register", SR.GetString(SR.SharingRegistrationFailed, status.ToString())), this, null);
                }
                if (TD.MessageQueueRegisterFailedIsEnabled())
                {
                    TD.MessageQueueRegisterFailed(this.EventTraceActivity,
                        (path != null) ? path.ToString() : string.Empty, 
                        status.ToString());
                }

                InitiateClosingServiceInstance();
            }

            return status;
        }