| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using CoreWCF.Channels; |
| | | 6 | | |
| | | 7 | | namespace CoreWCF.Dispatcher |
| | | 8 | | { |
| | | 9 | | internal class SingletonInstanceContextProvider : InstanceContextProviderBase |
| | | 10 | | { |
| | | 11 | | private InstanceContext _singleton; |
| | | 12 | | private readonly object _thisLock; |
| | | 13 | | |
| | | 14 | | internal SingletonInstanceContextProvider(DispatchRuntime dispatchRuntime) |
| | 125 | 15 | | : base(dispatchRuntime) |
| | | 16 | | { |
| | 125 | 17 | | _thisLock = new object(); |
| | 125 | 18 | | } |
| | | 19 | | |
| | | 20 | | internal InstanceContext SingletonInstance |
| | | 21 | | { |
| | | 22 | | get |
| | | 23 | | { |
| | 183 | 24 | | if (_singleton == null) |
| | | 25 | | { |
| | 82 | 26 | | lock (_thisLock) |
| | | 27 | | { |
| | 82 | 28 | | if (_singleton == null) |
| | | 29 | | { |
| | 82 | 30 | | InstanceContext instanceContext = DispatchRuntime.SingletonInstanceContext; |
| | | 31 | | |
| | 82 | 32 | | if (instanceContext == null) |
| | | 33 | | { |
| | 0 | 34 | | instanceContext = new InstanceContext(DispatchRuntime.ChannelDispatcher.Host, false); |
| | 0 | 35 | | instanceContext.OpenAsync().GetAwaiter().GetResult(); |
| | | 36 | | } |
| | 82 | 37 | | else if (instanceContext.State != CommunicationState.Opened) |
| | | 38 | | { |
| | | 39 | | // we need to lock against the instance context for open since two different endpoints c |
| | | 40 | | // share the same instance context, but different providers. So the provider lock does n |
| | | 41 | | // the open process |
| | 82 | 42 | | lock (instanceContext.ThisLock) |
| | | 43 | | { |
| | 82 | 44 | | if (instanceContext.State != CommunicationState.Opened) |
| | | 45 | | { |
| | 82 | 46 | | instanceContext.OpenAsync().GetAwaiter().GetResult(); |
| | | 47 | | } |
| | 82 | 48 | | } |
| | | 49 | | } |
| | | 50 | | |
| | | 51 | | //Set the IsUsercreated flag to false for singleton mode even in cases when users create the |
| | 82 | 52 | | instanceContext.IsUserCreated = false; |
| | | 53 | | |
| | | 54 | | //Delay assigning the potentially newly created InstanceContext (till after its opened) to t |
| | | 55 | | //to ensure that it is opened only once. |
| | 82 | 56 | | _singleton = instanceContext; |
| | | 57 | | } |
| | 82 | 58 | | } |
| | | 59 | | } |
| | 183 | 60 | | return _singleton; |
| | | 61 | | } |
| | | 62 | | } |
| | | 63 | | |
| | | 64 | | #region IInstanceContextProvider Members |
| | | 65 | | |
| | | 66 | | public override InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel) |
| | | 67 | | { |
| | 129 | 68 | | ServiceChannel serviceChannel = GetServiceChannelFromProxy(channel); |
| | 129 | 69 | | if (serviceChannel != null && serviceChannel.HasSession) |
| | | 70 | | { |
| | 54 | 71 | | SingletonInstance.BindIncomingChannel(serviceChannel); |
| | | 72 | | } |
| | 129 | 73 | | return SingletonInstance; |
| | | 74 | | } |
| | | 75 | | |
| | | 76 | | public override void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel |
| | | 77 | | { |
| | | 78 | | //no-op |
| | 0 | 79 | | } |
| | | 80 | | |
| | | 81 | | public override bool IsIdle(InstanceContext instanceContext) |
| | | 82 | | { |
| | | 83 | | //By default return false |
| | 0 | 84 | | return false; |
| | | 85 | | } |
| | | 86 | | |
| | | 87 | | public override void NotifyIdle(Action<InstanceContext> callback, InstanceContext instanceContext) |
| | | 88 | | { |
| | | 89 | | //no-op |
| | 0 | 90 | | } |
| | | 91 | | |
| | | 92 | | #endregion |
| | | 93 | | } |
| | | 94 | | } |