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
- PolicyStatement.cs
- DataGridTextBoxColumn.cs
- ApplicationCommands.cs
- XslCompiledTransform.cs
- DataSourceExpressionCollection.cs
- EventProviderClassic.cs
- XmlProcessingInstruction.cs
- DataGridViewCellMouseEventArgs.cs
- Metafile.cs
- ProfileGroupSettings.cs
- MsmqNonTransactedPoisonHandler.cs
- FilterInvalidBodyAccessException.cs
- XslUrlEditor.cs
- UrlPath.cs
- FirstMatchCodeGroup.cs
- XmlReaderSettings.cs
- DbProviderFactories.cs
- TypeResolver.cs
- PropertyValueChangedEvent.cs
- ConfigurationSectionCollection.cs
- DBConnection.cs
- _HelperAsyncResults.cs
- RelationshipDetailsRow.cs
- XamlPointCollectionSerializer.cs
- COM2Properties.cs
- WCFServiceClientProxyGenerator.cs
- RectangleHotSpot.cs
- DecimalStorage.cs
- SmtpNegotiateAuthenticationModule.cs
- Menu.cs
- _DomainName.cs
- LOSFormatter.cs
- DateTimeConverter.cs
- DesignerDataParameter.cs
- BuilderPropertyEntry.cs
- WebPartMovingEventArgs.cs
- recordstate.cs
- BindValidationContext.cs
- Transform.cs
- Border.cs
- XmlStringTable.cs
- GridItemProviderWrapper.cs
- SqlServices.cs
- _NativeSSPI.cs
- AuthStoreRoleProvider.cs
- BamlBinaryWriter.cs
- OperatingSystem.cs
- SizeFConverter.cs
- CommonRemoteMemoryBlock.cs
- CompilerLocalReference.cs
- SqlErrorCollection.cs
- CheckBoxFlatAdapter.cs
- RelatedPropertyManager.cs
- FontStyle.cs
- ActivitySurrogate.cs
- CodeTypeDeclarationCollection.cs
- SafeThreadHandle.cs
- ResourcePool.cs
- NotFiniteNumberException.cs
- CategoriesDocument.cs
- AttachedProperty.cs
- CroppedBitmap.cs
- CodeArgumentReferenceExpression.cs
- Nodes.cs
- PrinterSettings.cs
- SiteMapSection.cs
- CodeSnippetTypeMember.cs
- SchemaTypeEmitter.cs
- DataColumnMapping.cs
- SqlClientFactory.cs
- MouseActionValueSerializer.cs
- TransformValueSerializer.cs
- SafeProcessHandle.cs
- GenericTypeParameterBuilder.cs
- Win32SafeHandles.cs
- ArraySet.cs
- BamlRecords.cs
- ResourceProviderFactory.cs
- DelayDesigner.cs
- ToolStripCustomTypeDescriptor.cs
- MediaPlayer.cs
- DataControlExtensions.cs
- CaseExpr.cs
- DocumentPage.cs
- ListInitExpression.cs
- TemplatePagerField.cs
- FormClosedEvent.cs
- UpDownBaseDesigner.cs
- BitStack.cs
- MulticastDelegate.cs
- WindowsComboBox.cs
- ServiceDesigner.cs
- WebHeaderCollection.cs
- FactoryMaker.cs
- XmlBoundElement.cs
- XhtmlMobileTextWriter.cs
- TextRangeProviderWrapper.cs
- PackageRelationship.cs
- URLEditor.cs
- RijndaelCryptoServiceProvider.cs