Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / SMSvcHost / System / ServiceModel / Activation / WorkerProcess.cs / 1 / WorkerProcess.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Activation { using System; using System.Threading; using System.Diagnostics; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Diagnostics; using System.ServiceModel.Activation.Diagnostics; using System.Globalization; using System.Security.AccessControl; using System.Reflection; using System.IO; using StringTraceRecord = System.ServiceModel.Diagnostics.StringTraceRecord; [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] abstract class WorkerProcess : IConnectionRegister { int isUnregistered; int processId; MessageQueue queue; int queueId; IConnectionDuplicator connectionDuplicator; public bool IsRegistered { get { return isUnregistered == 0; } } public MessageQueue Queue { get { return this.queue; } set { this.queue = value; } } public int ProcessId { get { return this.processId; } } #if DEBUG public int QueueId { get { return this.queueId; } } #endif internal void Close() { if (Interlocked.Increment(ref isUnregistered) == 1) { if (this.queue != null) { this.queue.Unregister(this); } } } protected abstract DuplicateContext DuplicateConnection(ListenerSessionConnection session); protected abstract void OnDispatchSuccess(); protected abstract TransportType TransportType { get; } internal IAsyncResult BeginDispatchSession(ListenerSessionConnection session, AsyncCallback callback, object state) { return new DispatchSessionAsyncResult(session, callback, state); } internal bool EndDispatchSession(IAsyncResult result) { try { DispatchSessionAsyncResult dispatchAsyncResult = DispatchSessionAsyncResult.End(result); if (dispatchAsyncResult.DuplicateSucceeded) { OnDispatchSuccess(); return true; } } catch (Exception exception) { EventLogEventId logEventId = EventLogEventId.MessageQueueDuplicatedSocketLeak; if (this.TransportType == TransportType.NamedPipe) { logEventId = EventLogEventId.MessageQueueDuplicatedPipeLeak; } Debug.Print("WorkerProcess.DispatchSession() failed sending duplicated socket to processId: " + this.ProcessId + " exception:" + exception); DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, EventLogCategory.SharingService, logEventId, this.ProcessId.ToString(NumberFormatInfo.InvariantInfo), System.ServiceModel.Diagnostics.DiagnosticTrace.CreateSourceString(this), exception.ToString()); if (DiagnosticUtility.IsFatal(exception)) { throw; } Close(); // make sure we close the connection to the SharedConnectionListener // so it knows we've unregistered it ((IChannel)connectionDuplicator).Abort(); if (!ShouldRecoverFromProxyCall(exception)) { throw; } } return false; } internal IConnectionDuplicator ConnectionDuplicator { get { return this.connectionDuplicator; } } void WorkerProcess_Closed(object sender, EventArgs e) { Debug.Print("WorkerProcess.WorkerProcess_Closed() worker leaving: " + processId + " State: " + ((IDuplexContextChannel)sender).State); Close(); } void WorkerProcess_Faulted(object sender, EventArgs e) { Debug.Print("WorkerProcess.WorkerProcess_Faulted() worker leaving: " + processId + " State: " + ((IDuplexContextChannel)sender).State); Close(); } ListenerExceptionStatus IConnectionRegister.Register(Version version, int processId, BaseUriWithWildcard path, int queueId, Guid token, string eventName) { Debug.Print("WorkerProcess.Register() version: " + version + " processId: " + processId + " path: " + path + " queueId: " + queueId + " token: " + token + " eventName: " + eventName); if (DiagnosticUtility.ShouldTraceInformation) { ListenerTraceUtility.TraceEvent(TraceEventType.Information, TraceCode.MessageQueueRegisterCalled, new StringTraceRecord("Path", path.ToString()), this, null); } // Get the callback channel this.connectionDuplicator = OperationContext.Current.GetCallbackChannel(); 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]; DiagnosticUtility.DebugAssert(property != null, "WorkerProcess.Register() ConnectionMessageProperty not found!"); IConnection connection = property as IConnection; DiagnosticUtility.DebugAssert(connection != null, "WorkerProcess.Register() ConnectionMessageProperty is not IConnection!"); PipeHandle pipe = connection.GetCoreTransport() as PipeHandle; DiagnosticUtility.DebugAssert(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 (DiagnosticUtility.IsFatal(exception)) { throw; } if (DiagnosticUtility.ShouldTraceError) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Error); } status = ListenerExceptionStatus.InvalidArgument; abortInstance = true; } } if (status != ListenerExceptionStatus.Success) { goto FAILED; } if (DiagnosticUtility.ShouldTraceInformation) { ListenerTraceUtility.TraceEvent(TraceEventType.Information, TraceCode.MessageQueueRegisterSucceeded, new StringTraceRecord("Path", path.ToString()), this, null); } FAILED: if (abortInstance) { if (DiagnosticUtility.ShouldTraceError) { ListenerTraceUtility.TraceEvent(TraceEventType.Error, TraceCode.MessageQueueRegisterFailed, new StringTraceRecord("Register", SR.GetString(SR.SharingRegistrationFailedAndAbort, status.ToString())), this, null); } AbortServiceInstance(); } else if (status != ListenerExceptionStatus.Success) { if (DiagnosticUtility.ShouldTraceError) { ListenerTraceUtility.TraceEvent(TraceEventType.Error, TraceCode.MessageQueueRegisterFailed, new StringTraceRecord("Register", SR.GetString(SR.SharingRegistrationFailed, status.ToString())), this, null); } InitiateClosingServiceInstance(); } return status; } bool IConnectionRegister.ValidateUriRoute(Uri uri, System.Net.IPAddress address, int port) { if (this.queue == null) { AbortServiceInstance(); return false; } MessageQueue destinationQueue = RoutingTable.Lookup(uri, address, port); return object.ReferenceEquals(destinationQueue, this.queue); } void IConnectionRegister.Unregister() { Debug.Print("WorkerProcess.Unregister() processId: " + processId); Close(); } static bool ShouldRecoverFromProxyCall(Exception exception) { return ( (exception is CommunicationException) || (exception is ObjectDisposedException) || (exception is TimeoutException) ); } void AbortServiceInstance() { OperationContext.Current.InstanceContext.Abort(); } void InitiateClosingServiceInstance() { InstanceContext serviceInstance = OperationContext.Current.InstanceContext; serviceInstance.BeginClose(ListenerConstants.RegistrationCloseTimeout, DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(CloseCallback)), serviceInstance); } static void CloseCallback(IAsyncResult asyncResult) { InstanceContext serviceInstance = asyncResult.AsyncState as InstanceContext; try { serviceInstance.EndClose(asyncResult); } catch (CommunicationException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } catch (TimeoutException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } } class DispatchSessionAsyncResult : AsyncResult { ListenerSessionConnection session; bool duplicateSucceeded; static AsyncCallback dispatchSessionCallback = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(DispatchSessionCompletedCallback)); public DispatchSessionAsyncResult(ListenerSessionConnection session, AsyncCallback callback, object state) : base(callback, state) { this.session = session; DuplicateContext duplicateContext = session.WorkerProcess.DuplicateConnection(session); if (duplicateContext == null) { // Failed in duplicate connection data. this.Complete(true); } IAsyncResult result = this.session.WorkerProcess.ConnectionDuplicator.BeginDuplicate(duplicateContext, dispatchSessionCallback, this); if (result.CompletedSynchronously) { CompleteDuplicateSession(result); this.Complete(true); } } static void DispatchSessionCompletedCallback(IAsyncResult result) { if (result.CompletedSynchronously) return; DispatchSessionAsyncResult thisPtr = (DispatchSessionAsyncResult)result.AsyncState; Exception completeException = null; try { thisPtr.CompleteDuplicateSession(result); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception exception) { if (DiagnosticUtility.IsFatal(exception)) { throw; } completeException = exception; } thisPtr.Complete(false, completeException); } void CompleteDuplicateSession(IAsyncResult result) { this.session.WorkerProcess.ConnectionDuplicator.EndDuplicate(result); // Successfully duplicated the session. duplicateSucceeded = true; } public bool DuplicateSucceeded { get { return duplicateSucceeded; } } public static DispatchSessionAsyncResult End(IAsyncResult result) { return AsyncResult.End (result); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PackWebResponse.cs
- XmlEntityReference.cs
- ProjectionPruner.cs
- followingsibling.cs
- SchemaAttDef.cs
- DateTimeSerializationSection.cs
- CompressionTransform.cs
- WindowsListViewItemCheckBox.cs
- NamedPermissionSet.cs
- XmlSchemaObject.cs
- XmlAttributeCache.cs
- ToolStripItemClickedEventArgs.cs
- CodeExporter.cs
- ModuleElement.cs
- WebPartConnectionsConfigureVerb.cs
- sqlpipe.cs
- StrongNameKeyPair.cs
- LiteralTextContainerControlBuilder.cs
- ValidationResult.cs
- TranslateTransform3D.cs
- PageWrapper.cs
- CollectionViewSource.cs
- ClassDataContract.cs
- columnmapkeybuilder.cs
- NetworkInterface.cs
- NegatedConstant.cs
- MsmqIntegrationProcessProtocolHandler.cs
- XmlUtil.cs
- DATA_BLOB.cs
- BamlLocalizableResourceKey.cs
- X509Utils.cs
- MappingException.cs
- ContractNamespaceAttribute.cs
- FileChangesMonitor.cs
- cookie.cs
- SlipBehavior.cs
- _OSSOCK.cs
- DataRowComparer.cs
- FilterElement.cs
- ListItemCollection.cs
- JapaneseCalendar.cs
- GenericIdentity.cs
- MessageEventSubscriptionService.cs
- ScrollData.cs
- HashLookup.cs
- SmtpNtlmAuthenticationModule.cs
- X509Logo.cs
- RegexReplacement.cs
- WeakKeyDictionary.cs
- XmlSchemaSubstitutionGroup.cs
- CellPartitioner.cs
- ToolStripItemImageRenderEventArgs.cs
- SslStream.cs
- Queue.cs
- BuildManager.cs
- PatternMatcher.cs
- ImageMetadata.cs
- SaveRecipientRequest.cs
- ButtonChrome.cs
- TimeSpanOrInfiniteConverter.cs
- CodeAccessSecurityEngine.cs
- SubMenuStyle.cs
- ProcessModule.cs
- ColorTransformHelper.cs
- ControlBuilderAttribute.cs
- TypeElement.cs
- OleDbConnection.cs
- ValidationEventArgs.cs
- SafeNativeMethodsMilCoreApi.cs
- ThemeableAttribute.cs
- VerticalAlignConverter.cs
- _OverlappedAsyncResult.cs
- MsmqAppDomainProtocolHandler.cs
- BaseParser.cs
- ChameleonKey.cs
- ChangePassword.cs
- AssemblyResolver.cs
- SamlAuthorityBinding.cs
- _KerberosClient.cs
- UnsafeNativeMethods.cs
- Merger.cs
- ExceptQueryOperator.cs
- ColumnWidthChangedEvent.cs
- DataGridViewRowPrePaintEventArgs.cs
- NativeMethodsCLR.cs
- DataGridViewImageCell.cs
- QilCloneVisitor.cs
- versioninfo.cs
- CellIdBoolean.cs
- _Events.cs
- MarshalDirectiveException.cs
- DesignerActionKeyboardBehavior.cs
- fixedPageContentExtractor.cs
- ModelItemExtensions.cs
- ConfigUtil.cs
- DataGridViewRowsRemovedEventArgs.cs
- COM2Properties.cs
- CodeArgumentReferenceExpression.cs
- XmlArrayItemAttributes.cs
- ExtendedTransformFactory.cs