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
- ContentFileHelper.cs
- PropertyItem.cs
- TypeInformation.cs
- MailHeaderInfo.cs
- ClientType.cs
- Rules.cs
- IndependentAnimationStorage.cs
- LocalizeDesigner.cs
- SkinIDTypeConverter.cs
- ViewLoader.cs
- RowBinding.cs
- DataKeyArray.cs
- EventMap.cs
- XmlUtf8RawTextWriter.cs
- SmtpSection.cs
- TextEncodedRawTextWriter.cs
- WaitForChangedResult.cs
- ICollection.cs
- XmlObjectSerializerReadContextComplexJson.cs
- ToggleButtonAutomationPeer.cs
- LambdaCompiler.Unary.cs
- WorkerRequest.cs
- JulianCalendar.cs
- FixedFlowMap.cs
- RenderContext.cs
- DataList.cs
- SqlCacheDependencyDatabaseCollection.cs
- BindingContext.cs
- _ContextAwareResult.cs
- DBConnectionString.cs
- DockPatternIdentifiers.cs
- ArcSegment.cs
- SqlDataReader.cs
- DrawingBrush.cs
- AssociationEndMember.cs
- DrawingGroup.cs
- AssertFilter.cs
- PropertyDescriptor.cs
- Figure.cs
- WindowsFormsHost.cs
- SystemFonts.cs
- RowParagraph.cs
- BaseTemplateBuildProvider.cs
- BaseProcessor.cs
- ChineseLunisolarCalendar.cs
- complextypematerializer.cs
- InfoCardRSAPKCS1KeyExchangeDeformatter.cs
- PropertyIDSet.cs
- InputScope.cs
- XmlSchema.cs
- DataGridRowClipboardEventArgs.cs
- ReflectionServiceProvider.cs
- EventLogPermission.cs
- XslException.cs
- SpecialFolderEnumConverter.cs
- PackageStore.cs
- TextViewBase.cs
- BaseCollection.cs
- X500Name.cs
- BinaryFormatter.cs
- HttpModuleCollection.cs
- Baml2006ReaderContext.cs
- TextEditor.cs
- WindowsButton.cs
- CodeCompiler.cs
- FtpRequestCacheValidator.cs
- TextLine.cs
- DataSourceCache.cs
- ZipIOLocalFileDataDescriptor.cs
- UserControl.cs
- CustomErrorsSection.cs
- ListViewInsertedEventArgs.cs
- WebConfigurationHost.cs
- LayoutDump.cs
- Vertex.cs
- TraceLevelStore.cs
- NumberFormatter.cs
- GeneralTransformGroup.cs
- SymbolDocumentInfo.cs
- FontStyle.cs
- StateMachineHelpers.cs
- StatusBarItem.cs
- SiteMapDataSourceView.cs
- NotCondition.cs
- ArgumentElement.cs
- NamedPipeHostedTransportConfiguration.cs
- TransformedBitmap.cs
- LogManagementAsyncResult.cs
- ProgressBarBrushConverter.cs
- localization.cs
- BitmapMetadataBlob.cs
- SvcMapFileLoader.cs
- SqlCharStream.cs
- XmlDomTextWriter.cs
- EncoderParameters.cs
- ListItemDetailViewAttribute.cs
- HtmlInputPassword.cs
- Encoder.cs
- CreateUserWizard.cs
- QilExpression.cs