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
- XPathAxisIterator.cs
- CorrelationToken.cs
- ToolboxBitmapAttribute.cs
- BigInt.cs
- Triplet.cs
- XmlBoundElement.cs
- CustomAttribute.cs
- IntSecurity.cs
- ToolstripProfessionalRenderer.cs
- PixelFormat.cs
- TextProperties.cs
- ModifiableIteratorCollection.cs
- FormsAuthentication.cs
- SqlMethodAttribute.cs
- QilCloneVisitor.cs
- RenderData.cs
- MediaTimeline.cs
- InteropBitmapSource.cs
- RubberbandSelector.cs
- MD5CryptoServiceProvider.cs
- Line.cs
- DrawingGroupDrawingContext.cs
- MobileTextWriter.cs
- ConfigurationManager.cs
- SqlMethodAttribute.cs
- ArgumentException.cs
- VisualStyleElement.cs
- Rectangle.cs
- ContentType.cs
- UTF32Encoding.cs
- ArraySegment.cs
- EncryptedType.cs
- XmlAttributeOverrides.cs
- RowToParametersTransformer.cs
- LicenseContext.cs
- CalloutQueueItem.cs
- ConnectionInterfaceCollection.cs
- ContractBase.cs
- ArrangedElementCollection.cs
- AttachedPropertyBrowsableAttribute.cs
- OptimisticConcurrencyException.cs
- PenThreadWorker.cs
- Misc.cs
- InkCanvasAutomationPeer.cs
- DbConnectionPoolIdentity.cs
- AttributeUsageAttribute.cs
- RequestTimeoutManager.cs
- PropertyDescriptorGridEntry.cs
- PolyQuadraticBezierSegment.cs
- TimeoutValidationAttribute.cs
- VisualBrush.cs
- DesignerActionVerbItem.cs
- ObjectViewListener.cs
- DictionaryMarkupSerializer.cs
- UserControlParser.cs
- WindowsFormsHost.cs
- PopupEventArgs.cs
- CallId.cs
- WorkflowCompensationBehavior.cs
- Identity.cs
- FormsAuthenticationModule.cs
- WorkflowOperationFault.cs
- Vector3DKeyFrameCollection.cs
- Drawing.cs
- XmlElementList.cs
- SoapExtensionStream.cs
- SmiMetaDataProperty.cs
- IDReferencePropertyAttribute.cs
- ClientSponsor.cs
- ByteAnimation.cs
- BindUriHelper.cs
- SplineQuaternionKeyFrame.cs
- UICuesEvent.cs
- WindowsSlider.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- StylusSystemGestureEventArgs.cs
- EventEntry.cs
- MenuItem.cs
- CssClassPropertyAttribute.cs
- CodeVariableReferenceExpression.cs
- ManualResetEvent.cs
- PointValueSerializer.cs
- SimpleBitVector32.cs
- Padding.cs
- SqlBuffer.cs
- SortDescription.cs
- MaskedTextBoxTextEditor.cs
- WebPartEditorApplyVerb.cs
- CodeGeneratorOptions.cs
- SignatureHelper.cs
- DisplayNameAttribute.cs
- Graphics.cs
- GenericXmlSecurityToken.cs
- UInt32.cs
- XmlNamedNodeMap.cs
- CommandConverter.cs
- DeflateStreamAsyncResult.cs
- ListViewAutomationPeer.cs
- FastPropertyAccessor.cs
- ToolboxItemSnapLineBehavior.cs