e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
106 lines
4.9 KiB
C#
106 lines
4.9 KiB
C#
//----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace System.ServiceModel.WasHosting
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.ServiceModel;
|
|
using System.Web;
|
|
using System.Web.Hosting;
|
|
using System.ServiceModel.Channels;
|
|
using System.ServiceModel.Activation;
|
|
using System.Runtime;
|
|
|
|
abstract class BaseProcessProtocolHandler : ProcessProtocolHandler
|
|
{
|
|
string protocolId;
|
|
IAdphManager adphManager;
|
|
|
|
// Mapping from listenerChannelId->listenerChannelContext (i.e. IAdphManager, appId)
|
|
Dictionary<int, ListenerChannelContext> listenerChannelIdMapping = new Dictionary<int, ListenerChannelContext>();
|
|
|
|
[SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode,
|
|
Justification = "Instantiated by ASP.NET")]
|
|
protected BaseProcessProtocolHandler(string protocolId)
|
|
: base()
|
|
{
|
|
this.protocolId = protocolId;
|
|
}
|
|
|
|
internal virtual void HandleStartListenerChannelError(IListenerChannelCallback listenerChannelCallback, Exception ex)
|
|
{
|
|
// This is the workaround to let WAS know that the LC is started and then gracefully stopped.
|
|
listenerChannelCallback.ReportStarted();
|
|
listenerChannelCallback.ReportStopped(0);
|
|
}
|
|
|
|
// Start per-process listening for messages
|
|
public override void StartListenerChannel(IListenerChannelCallback listenerChannelCallback, IAdphManager adphManager)
|
|
{
|
|
DiagnosticUtility.DebugAssert(listenerChannelCallback != null, "The listenerChannelCallback parameter must not be null");
|
|
DiagnosticUtility.DebugAssert(adphManager != null, "The adphManager parameter must not be null");
|
|
|
|
int channelId = listenerChannelCallback.GetId();
|
|
ListenerChannelContext listenerChannelContext;
|
|
lock (this.listenerChannelIdMapping)
|
|
{
|
|
if (!listenerChannelIdMapping.TryGetValue(channelId, out listenerChannelContext))
|
|
{
|
|
int listenerChannelDataLength = listenerChannelCallback.GetBlobLength();
|
|
byte[] listenerChannelData = new byte[listenerChannelDataLength];
|
|
listenerChannelCallback.GetBlob(listenerChannelData, ref listenerChannelDataLength);
|
|
Debug.Print("BaseProcessProtocolHandler.StartListenerChannel() GetBlob() contains " + listenerChannelDataLength + " bytes");
|
|
listenerChannelContext = ListenerChannelContext.Hydrate(listenerChannelData);
|
|
this.listenerChannelIdMapping.Add(channelId, listenerChannelContext);
|
|
Debug.Print("BaseProcessProtocolHandler.StartListenerChannel() listenerChannelContext.ListenerChannelId: " + listenerChannelContext.ListenerChannelId);
|
|
}
|
|
}
|
|
|
|
if (this.adphManager == null)
|
|
{
|
|
this.adphManager = adphManager;
|
|
}
|
|
|
|
try
|
|
{
|
|
// wether or not a previous AppDomain was running, we're going to start a new one now:
|
|
Debug.Print("BaseProcessProtocolHandler.StartListenerChannel() calling StartAppDomainProtocolListenerChannel(appKey:" + listenerChannelContext.AppKey + " protocolId:" + protocolId + ")");
|
|
adphManager.StartAppDomainProtocolListenerChannel(listenerChannelContext.AppKey, protocolId, listenerChannelCallback);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (Fx.IsFatal(ex))
|
|
{
|
|
throw;
|
|
}
|
|
|
|
DiagnosticUtility.TraceHandledException(ex, TraceEventType.Error);
|
|
|
|
HandleStartListenerChannelError(listenerChannelCallback, ex);
|
|
}
|
|
}
|
|
|
|
public override void StopProtocol(bool immediate)
|
|
{
|
|
Debug.Print("BaseProcessProtocolHandler.StopProtocol(protocolId:" + protocolId + ", immediate:" + immediate + ")");
|
|
}
|
|
|
|
public override void StopListenerChannel(int listenerChannelId, bool immediate)
|
|
{
|
|
Debug.Print("BaseProcessProtocolHandler.StopListenerChannel(protocolId:" + protocolId + ", listenerChannelId:" + listenerChannelId + ", immediate:" + immediate + ")");
|
|
ListenerChannelContext listenerChannelContext = this.listenerChannelIdMapping[listenerChannelId];
|
|
adphManager.StopAppDomainProtocolListenerChannel(listenerChannelContext.AppKey, protocolId, listenerChannelId, immediate);
|
|
|
|
lock (this.listenerChannelIdMapping)
|
|
{
|
|
// Remove the channel id.
|
|
this.listenerChannelIdMapping.Remove(listenerChannelId);
|
|
}
|
|
}
|
|
}
|
|
}
|