Ejemplo n.º 1
0
 public void DisposableActionTest()
 {
     var a = 0;
     var disposal = new DisposableAction(() => a++);
     disposal.Dispose();
     Assert.Equal(1, a);
 }
Ejemplo n.º 2
0
    public DisposableArray(int minimumLength)
    {
        MinimumLength = minimumLength;
        Array         = s_arrayPool.Rent(MinimumLength);

        _disposableAction = new DisposableAction(ReturnArray);
    }
Ejemplo n.º 3
0
        public IDisposable EnterWriteLock()
        {
            var release = new DisposableAction(() => Monitor.Exit(inner));

            Monitor.Enter(inner);
            return(release);
        }
Ejemplo n.º 4
0
        private static IDisposable LocalGetDocumentStores(string[] urls, string database, out IDocumentStore[] stores)
        {
            stores = new IDocumentStore[urls.Length];
            var internalStore = stores;
            var disposable    = new DisposableAction(() =>
            {
                foreach (var s in internalStore)
                {
                    try
                    {
                        s?.Dispose();
                    }
                    catch
                    {
                        // ignored
                    }
                }
            });

            for (int i = 0; i < urls.Length; i++)
            {
                var store = new DocumentStore {
                    Urls = new[] { urls[i] }, Database = database, Conventions = new DocumentConventions {
                        DisableTopologyUpdates = true
                    }
                }
                .Initialize();
                stores[i] = store;
            }

            return(disposable);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Plays the provided audio source to the A-Leg.
        /// Dispose the returned token to cancel playback.
        /// </summary>
        /// <param name="file">The audio source.</param>
        /// <returns>An <seealso cref="IDisposable"/> which can be disposed to stop the audio.</returns>
        public async Task <IDisposable> PlayUntilCancelled(string file)
        {
            if (!CanPlayBackAudio)
            {
                Log.Warn(() => "Channel [{0}] attempted to play hold music when not answered".Fmt(UUID));
                return(Task.FromResult(new DisposableAction()));
            }

            // essentially, we'll do a playback application call without waiting for the ChannelExecuteComplete event
            // the caller can .Dispose() the returned token to do a uuid_break on the channel to kill audio.
            await eventSocket.SendCommand(string.Format("sendmsg {0}\ncall-command: execute\nexecute-app-name: playback\nexecute-app-arg:{1}\nloops:-1", UUID, file));

            var cancellation = new DisposableAction(
                async() =>
            {
                if (!CanPlayBackAudio)
                {
                    return;
                }

                try
                {
                    await eventSocket.Api("uuid_break", UUID);
                }
                catch (Exception ex)
                {
                    Log.ErrorException("Error calling 'api uuid_break {0}'".Fmt(UUID), ex);
                }
            });

            return(cancellation);
        }
Ejemplo n.º 6
0
        public bool SendEmail(EmailMessage emailMessage)
        {
            string sTo = emailMessage.EmailAddresses.RecipientList.Count > 0
                             ? emailMessage.EmailAddresses.RecipientList.ElementAt(0)
                             : String.Empty;

            // The modified using statement below adds the flexibility of controlling the disposal of the
            // MailMessage object. This is required to ensure that we can delay disposal for tests to test
            // certain properties while the production code is disposed as normal.
            using (
                DisposableAction <MailMessage> disposableMail =
                    CreateDisposableMail(emailMessage.EmailAddresses.From, sTo))
            {
                MailMessage mailMessage = disposableMail.Value;

                AddTos(emailMessage.EmailAddresses, mailMessage);
                AddCcs(emailMessage.EmailAddresses, mailMessage);
                AddBccs(emailMessage.EmailAddresses, mailMessage);
                AddReplyToIfDefined(emailMessage.EmailAddresses, mailMessage);
                AddAttachments(mailMessage, emailMessage.AttachmentPath);
                foreach (var attachmentStreamEntry in emailMessage.AttachmentStreams)
                {
                    AddAttachments(mailMessage, attachmentStreamEntry.Value, attachmentStreamEntry.Key);
                }

                mailMessage.Subject = String.IsNullOrEmpty(emailMessage.Subject)
                                          ? Application.ProductName
                                          : emailMessage.Subject;
                mailMessage.Body       = emailMessage.Body;
                mailMessage.IsBodyHtml = emailMessage.IsHtmlBody;

                DoSendMail(Host, mailMessage);
            }
            return(true);
        }
Ejemplo n.º 7
0
		public TransactionalStorage(InMemoryRavenConfiguration configuration, Action onCommit)
		{
			this.configuration = configuration;
			this.onCommit = onCommit;
			documentCacher = new DocumentCacher(configuration);
		    exitLockDisposable = new DisposableAction(() => Monitor.Exit(this));
		}
Ejemplo n.º 8
0
 public TransactionalStorage(InMemoryRavenConfiguration configuration, Action onCommit)
 {
     this.configuration = configuration;
     this.onCommit      = onCommit;
     documentCacher     = new DocumentCacher(configuration);
     exitLockDisposable = new DisposableAction(() => Monitor.Exit(this));
 }
Ejemplo n.º 9
0
        public unsafe SafeHGlobalHandle ReadImage()
        {
            SafeHGlobalHandle result = new SafeHGlobalHandle(GetImageSize());
            byte *            ptr    = (byte *)result.DangerousGetHandle().ToPointer();

            using (DisposableAction insurance = new DisposableAction(result.Dispose))
            {
                for (int y = 0; y < _header.BlockCount; y++)
                {
                    byte *blockPtr = ptr + y * _header.BlockSize * 2;

                    for (int x = 0, i = 0; x < _header.BlockSize; x++)
                    {
                        byte b = (byte)_input.ReadByte();

                        *(blockPtr + i)     = (byte)(b & 0x33);
                        *(blockPtr + i + 8) = (byte)((b >> 2) & 0x33);
                        if (++i % 8 == 0)
                        {
                            i += 8;
                        }
                    }
                }

                insurance.Cancel();
            }

            return(result);
        }
Ejemplo n.º 10
0
 public static TypeRule Rule(this Func<Type, bool> t, out IDisposable unreg)
 {
     t.AssertNotNull();
     var rule = new TypeRule(t);
     Repository.Rules.Add(rule);
     unreg = new DisposableAction(() => Repository.Rules.Remove(rule));
     return rule;
 }
Ejemplo n.º 11
0
		public TransactionalStorage(InMemoryRavenConfiguration configuration, Action onCommit)
		{
			this.configuration = configuration;
			this.onCommit = onCommit;
			documentCacher = new DocumentCacher(configuration);
			exitLockDisposable = new DisposableAction(() => Monitor.Exit(this));
            bufferPool = new BufferPool(configuration.Storage.Voron.MaxBufferPoolSize * 1024 * 1024 * 1024, int.MaxValue); // 2GB max buffer size (voron limit)
		}
Ejemplo n.º 12
0
        public void DisposableActionCalledOnDispose()
        {
            bool disposableCalled = false;

            using (DisposableAction action = new DisposableAction(delegate { disposableCalled = true; }))
            {}
            Assert.IsTrue(disposableCalled);
        }
Ejemplo n.º 13
0
 public TransactionalStorage(InMemoryRavenConfiguration configuration, Action onCommit)
 {
     this.configuration = configuration;
     this.onCommit      = onCommit;
     documentCacher     = new DocumentCacher(configuration);
     exitLockDisposable = new DisposableAction(() => Monitor.Exit(this));
     bufferPool         = new BufferPool(configuration.Storage.Voron.MaxBufferPoolSize * 1024 * 1024 * 1024, int.MaxValue); // 2GB max buffer size (voron limit)
 }
Ejemplo n.º 14
0
 public static PropertyRule Rule(this Func<PropertyInfo, bool> pi, out IDisposable unreg)
 {
     pi.AssertNotNull();
     var rule = new PropertyRule(pi);
     Repository.Rules.Add(rule);
     unreg = new DisposableAction(() => Repository.Rules.Remove(rule));
     return rule;
 }
        private IDisposable RegisterDebugWindowHook(IWebView current, IWebView debugWebView)
        {
            var disp         = _WebViewCommunication.Connect(current, debugWebView);
            var disp2        = _WebViewCommunication.Subscribe(debugWebView, "main:inject", _ => InjectBackend(current));
            var disconnector = new DisposableAction(() => _WebViewCommunication.Disconnect(debugWebView));

            return(new ComposedDisposable(disp, disp2, disconnector));
        }
Ejemplo n.º 16
0
        public virtual IDisposable Subscribe(ISubscriber subscriber, string cursor, Func <MessageResult, object, Task <bool> > callback, int maxMessages, object state)
        {
            if (subscriber == null)
            {
                throw new ArgumentNullException("subscriber");
            }

            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            Subscription subscription = CreateSubscription(subscriber, cursor, callback, maxMessages, state);

            // Set the subscription for this subscriber
            subscriber.Subscription = subscription;

            var topics = new HashSet <Topic>();

            foreach (var key in subscriber.EventKeys)
            {
                // Create or retrieve topic and set it as HasSubscriptions
                Topic topic = SubscribeTopic(key);

                // Set the subscription for this topic
                subscription.SetEventTopic(key, topic);

                topics.Add(topic);
            }

            subscriber.EventKeyAdded   += _addEvent;
            subscriber.EventKeyRemoved += _removeEvent;
            subscriber.WriteCursor      = subscription.WriteCursor;

            var subscriptionState = new SubscriptionState(subscriber);
            var disposable        = new DisposableAction(_disposeSubscription, subscriptionState);

            // When the subscription itself is disposed then dispose it
            subscription.Disposable = disposable;

            // Add the subscription when it's all set and can be scheduled
            // for work. It's important to do this after everything is wired up for the
            // subscription so that publishes can schedule work at the right time.
            foreach (var topic in topics)
            {
                topic.AddSubscription(subscription);
            }

            subscriptionState.Initialized.Set();

            // If there's a cursor then schedule work for this subscription
            if (!String.IsNullOrEmpty(cursor))
            {
                _broker.Schedule(subscription);
            }

            return(disposable);
        }
Ejemplo n.º 17
0
        public void should_call_action_on_dispose()
        {
            var callCount        = 0;
            var disposableObject = new DisposableAction(() => callCount++);

            disposableObject.Dispose();

            callCount.ShouldEqual(1);
        }
        public void WillNotThrowException()
        {
            int count = 0;
            var disposable1 = new DisposableAction(() => { throw new Exception(); });
            var newDisp = disposable1.ComposeWith(disposable1);
            newDisp.Dispose();

            count.Should().Be(0);
        }
        public void AvoidDeadlockIfCancellationTokenTriggeredBeforeSubscribing()
        {
            var response = new Mock<IResponse>();
            response.Setup(m => m.CancellationToken).Returns(CancellationToken.None);
            var request = new Mock<IRequest>();
            var qs = new NameValueCollection();
            qs["connectionId"] = "1";
            request.Setup(m => m.QueryString).Returns(qs);
            request.Setup(m => m.Url).Returns(new Uri("http://test/echo/connect"));
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = new JsonNetSerializer();
            var hostContext = new HostContext(request.Object, response.Object);
            var transportConnection = new Mock<ITransportConnection>();
            var traceManager = new Mock<ITraceManager>();
            traceManager.Setup(m => m[It.IsAny<string>()]).Returns(new System.Diagnostics.TraceSource("foo"));

            Func<PersistentResponse, object, Task<bool>> callback = null;
            object state = null;

            var disposable = new DisposableAction(() =>
            {
                callback(new PersistentResponse() { Terminal = true }, state);
            });

            transportConnection.Setup(m => m.Receive(It.IsAny<string>(),
                                                     It.IsAny<Func<PersistentResponse, object, Task<bool>>>(),
                                                     It.IsAny<int>(),
                                                     It.IsAny<object>())).Callback<string, Func<PersistentResponse, object, Task<bool>>, int, object>((id, cb, max, st) =>
                                                     {
                                                         callback = cb;
                                                         state = st;
                                                     })
                                                     .Returns(disposable);

            var transport = new Mock<ForeverTransport>(hostContext, json, heartBeat.Object, counters.Object, traceManager.Object)
            {
                CallBase = true
            };

            var wh = new ManualResetEventSlim();

            transport.Object.BeforeCancellationTokenCallbackRegistered = () =>
            {
                // Trip the cancellation token
                transport.Object.End();
            };

            // Act
            Task.Factory.StartNew(() =>
            {
                transport.Object.ProcessRequest(transportConnection.Object);
                wh.Set();
            });

            Assert.True(wh.Wait(TimeSpan.FromSeconds(2)), "Dead lock!");
        }
Ejemplo n.º 20
0
        public static PropertyRule Rule(this Func <PropertyInfo, bool> pi, out IDisposable unreg)
        {
            pi.AssertNotNull();
            var rule = new PropertyRule(pi);

            Repository.Rules.Add(rule);
            unreg = new DisposableAction(() => Repository.Rules.Remove(rule));
            return(rule);
        }
Ejemplo n.º 21
0
        public void DisposalActionRunsWhenDisposeIsCalled()
        {
            var disposeActionRan = false;
            var action           = new DisposableAction(() => {}, () => disposeActionRan = true);

            Assert.That(disposeActionRan, Is.False);
            action.Dispose();
            Assert.That(disposeActionRan, Is.True);
        }
Ejemplo n.º 22
0
        public static TypeRule Rule(this Func <Type, bool> t, out IDisposable unreg)
        {
            t.AssertNotNull();
            var rule = new TypeRule(t);

            Repository.Rules.Add(rule);
            unreg = new DisposableAction(() => Repository.Rules.Remove(rule));
            return(rule);
        }
        public void CanDisposeOneItem()
        {
            int count = 0;
            var disposable1 = new DisposableAction(() => count++);
            var newDisp = disposable1.ComposeWith();
            newDisp.Dispose();

            count.Should().Be(1);
        }
Ejemplo n.º 24
0
        public void Dispose_ActionExecuted()
        {
            bool        executed = false;
            IDisposable subject  = new DisposableAction(() => executed = true);

            Assert.That(executed, Is.False);
            subject.Dispose();
            Assert.That(executed, Is.True);
        }
        public void CanDisposeTwoItemsLIFO2()
        {
            int count = 7;
            var disposable1 = new DisposableAction(() => count %= 7);
            var disposable2 = new DisposableAction(() => count += 8);
            var newDisp = disposable2.ComposeWith(disposable1);
            newDisp.Dispose();

            count.Should().Be(8);
        }
        public void WillNotThrowException()
        {
            int count       = 0;
            var disposable1 = new DisposableAction(() => { throw new Exception(); });
            var newDisp     = disposable1.ComposeWith(disposable1);

            newDisp.Dispose();

            count.Should().Be(0);
        }
Ejemplo n.º 27
0
        public void ActionIsCalled()
        {
            bool called = false;

            void callMe() => called = true;

            using (_ = new DisposableAction(callMe)) { }

            Assert.IsTrue(called);
        }
        public void CanDisposeOneItem()
        {
            int count       = 0;
            var disposable1 = new DisposableAction(() => count++);
            var newDisp     = disposable1.ComposeWith();

            newDisp.Dispose();

            count.Should().Be(1);
        }
Ejemplo n.º 29
0
 public void DisposableActionParallelTest()
 {
     var a = 0;
     var disposal = new DisposableAction(() => a++);
     Parallel.For(1, 10, _ =>
     {
         disposal.Dispose();
     });
     Assert.Equal(1, a);
 }
Ejemplo n.º 30
0
		public IDisposable WithLockFor(string key)
		{
			using(globalLocker.EnterReadLock())
			{
				var locker = locks.GetOrAdd(key, new object());
				var release = new DisposableAction(() => Monitor.Exit(locker));
				Monitor.Enter(locker);
				return release;
			}
		}
Ejemplo n.º 31
0
        public void should_subscribe()
        {
            var expectedScope = new DisposableAction(() => { });
            var subscription  = new Subscription(MessageUtil.TypeId <FakeCommand>());

            _busMock.Setup(x => x.Subscribe(subscription, SubscriptionOptions.Default)).Returns(expectedScope);

            var scope = _bus.Subscribe(subscription);

            scope.ShouldEqual(expectedScope);
        }
Ejemplo n.º 32
0
        public void should_subscribe()
        {
            var expectedScope = new DisposableAction(() => { });
            var subscription  = new SubscriptionRequest(new Subscription(MessageUtil.TypeId <FakeCommand>()));

            _busMock.Setup(x => x.SubscribeAsync(subscription)).Returns(Task.FromResult <IDisposable>(expectedScope));

            var scope = _bus.SubscribeAsync(subscription);

            scope.Result.ShouldEqual(expectedScope);
        }
    private async Task <WeakReference> NoLeakWhenServerThrows_Helper()
    {
        var disposable = new DisposableAction(null);
        await Assert.ThrowsAsync <RemoteMethodNotFoundException>(() => this.clientRpc.InvokeWithCancellationAsync(
                                                                     "someMethod",
                                                                     new object?[] { disposable },
                                                                     new Type[] { typeof(IDisposable) },
                                                                     this.TimeoutToken));

        return(new WeakReference(disposable));
    }
Ejemplo n.º 34
0
        public override async Task <GLTexture> ReadTextureAsync(CancellationToken cancelationToken)
        {
            if (cancelationToken.IsCancellationRequested)
            {
                return(RaiseTextureReaded(null));
            }

            BitmapData bmdata = _bitmap.LockBits(new Rectangle(0, 0, _width, _height), ImageLockMode.ReadOnly, _format);

            using (DisposableAction unlocker = new DisposableAction(() => _bitmap.UnlockBits(bmdata)))
            {
                GLTexture texture;
                using (GLService.AcquireContext())
                    texture = new GLTexture(GL.GenTexture(), _width, _height, _format);

                using (DisposableAction insurance = new DisposableAction(texture.Dispose))
                {
                    if (cancelationToken.IsCancellationRequested)
                    {
                        return(RaiseTextureReaded(null));
                    }

                    using (GLService.AcquireContext())
                    {
                        GL.BindTexture(TextureTarget.Texture2D, texture.Id);
                        GL.TexImage2D(TextureTarget.Texture2D, 0, _format, bmdata.Width, bmdata.Height, 0, _format, _format, bmdata.Scan0);
                    }

                    //ErrorCode error = GL.GetError();
                    //if (error != ErrorCode.NoError)
                    //    throw new ArgumentException("Error building TexImage. GL Error: " + error);

                    _bitmap.UnlockBits(bmdata);
                    unlocker.Cancel();

                    if (cancelationToken.IsCancellationRequested)
                    {
                        return(RaiseTextureReaded(null));
                    }

                    using (GLService.AcquireContext())
                    {
                        GL.BindTexture(TextureTarget.Texture2D, texture.Id);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
                    }

                    insurance.Cancel();
                }
                return(RaiseTextureReaded(texture));
            }
        }
        public void CanDisposeTwoItemsLIFO2()
        {
            int count       = 7;
            var disposable1 = new DisposableAction(() => count %= 7);
            var disposable2 = new DisposableAction(() => count += 8);
            var newDisp     = disposable2.ComposeWith(disposable1);

            newDisp.Dispose();

            count.Should().Be(8);
        }
Ejemplo n.º 36
0
		public TransactionalStorage(InMemoryRavenConfiguration configuration, Action onCommit, Action onStorageInaccessible)
		{
			this.configuration = configuration;
			this.onCommit = onCommit;
			this.onStorageInaccessible = onStorageInaccessible;

			RecoverFromFailedCompact(configuration.DataDirectory);

			documentCacher = new DocumentCacher(configuration);
			exitLockDisposable = new DisposableAction(() => Monitor.Exit(this));
            bufferPool = new BufferPool(configuration.Storage.Voron.MaxBufferPoolSize * 1024 * 1024 * 1024, int.MaxValue); // 2GB max buffer size (voron limit)
		}
Ejemplo n.º 37
0
        public void DisposeActionOnlyExecutedOnceWhenCallingDisposeMultipleTimes()
        {
            var invokeCount = 0;
            var action      = new DisposableAction(() => { }, () => invokeCount++);

            action.Dispose();
            action.Dispose();
            action.Dispose();
            action.Dispose();
            action.Dispose();
            Assert.That(invokeCount, Is.EqualTo(1));
        }
Ejemplo n.º 38
0
        public void ActionIsExecutedOnDispose()
        {
            // Arrange
            bool             called = false;
            DisposableAction action = new DisposableAction(() => { called = true; });

            // Act
            action.Dispose();

            // Assert
            Assert.True(called, "The action was not run when the DisposableAction was disposed");
        }
Ejemplo n.º 39
0
        public void ActionIsExecutedOnDispose()
        {
            // Arrange
            bool called = false;
            DisposableAction action = new DisposableAction(() => { called = true; });

            // Act
            action.Dispose();

            // Assert
            Assert.True(called, "The action was not run when the DisposableAction was disposed");
        }
Ejemplo n.º 40
0
        public void SetDisposesIfShouldDispose()
        {
            bool disposed = false;
            var disposable = new DisposableAction(() => { disposed = true; });
            var disposer = new Disposer();

            Assert.False(disposed);
            disposer.Dispose();

            disposer.Set(disposable);
            Assert.True(disposed);
        }
Ejemplo n.º 41
0
        /// <summary>
        /// Logs a step.
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static IDisposable Step(this ILogger logger, string message)
        {
            var id = Guid.NewGuid().ToString();

            logger.Log(LogLevel.Trace, "step.start", message, new { id = id, time = DateTime.UtcNow });
            var disposable = new DisposableAction(() =>
            {
                logger.Log(LogLevel.Trace, "step.complete", message, new { id = id, time = DateTime.UtcNow });
            });

            return(disposable);
        }
Ejemplo n.º 42
0
        public IDisposable OverrideWriter(LogWriter new_out)
        {
            var old_out = Writer;
            Writer = new_out;
            var this_override = new DisposableAction(() => Writer = old_out);

            var debug_override = Debug.OverrideWriter(new_out);
            var info_override = Info.OverrideWriter(new_out);
            var warn_override = Warn.OverrideWriter(new_out);
            var error_override = Error.OverrideWriter(new_out);
            var fatal_override = Fatal.OverrideWriter(new_out);

            return this_override + debug_override + info_override + warn_override + error_override + fatal_override;
        }
        internal override void AssociateWithCurrentThread() {
            IDisposable disassociationAction = _state.Helper.EnterSynchronousControl();

#if DBG
            IDisposable capturedDisassociationAction = disassociationAction;
            Thread capturedThread = Thread.CurrentThread;
            disassociationAction = new DisposableAction(() => {
                Debug.Assert(capturedThread == Thread.CurrentThread, String.Format("AssociateWithCurrentThread was called on thread ID '{0}', but DisassociateFromCurrentThread was called on thread ID '{1}'.", capturedThread.ManagedThreadId, Thread.CurrentThread.ManagedThreadId));
                capturedDisassociationAction.Dispose();
            });
#endif

            // Don't need to synchronize access to SyncControlDisassociationActions since only one thread can call
            // EnterSynchronousControl() at a time.
            _state.SyncControlDisassociationActions.Push(disassociationAction);
        }
Ejemplo n.º 44
0
		public void Execute(DocumentDatabase database)
		{
			docDb = database;
			var replicationRequestTimeoutInMs =
				docDb.Configuration.GetConfigurationValue<int>("Raven/Replication/ReplicationRequestTimeout") ??
				60 * 1000;

			httpRavenRequestFactory = new HttpRavenRequestFactory { RequestTimeoutInMs = replicationRequestTimeoutInMs };

            var task = new Task(Execute, TaskCreationOptions.LongRunning);
			var disposableAction = new DisposableAction(task.Wait);
			// make sure that the doc db waits for the replication task shutdown
			docDb.ExtensionsState.GetOrAdd(Guid.NewGuid().ToString(), s => disposableAction);
			task.Start();
            

		}
Ejemplo n.º 45
0
		public void Execute(DocumentDatabase database)
		{
			docDb = database;
			var replicationRequestTimeoutInMs =
				docDb.Configuration.GetConfigurationValue<int>("Raven/Replication/ReplicationRequestTimeout") ??
				60 * 1000;

			httpRavenRequestFactory = new HttpRavenRequestFactory { RequestTimeoutInMs = replicationRequestTimeoutInMs };

			var thread = new Thread(Execute)
			{
				IsBackground = true,
				Name = "Replication Thread"
			};
			var disposableAction = new DisposableAction(thread.Join);
			// make sure that the doc db waits for the replication thread shutdown
			docDb.ExtensionsState.GetOrAdd(Guid.NewGuid().ToString(), s => disposableAction);
			thread.Start();


		}
Ejemplo n.º 46
0
 protected void MultiplexLogs(IEnumerable<Logger> loggers) { loggers.ForEach(logger => _teardown += logger.OverrideWriter(_writer)); }
Ejemplo n.º 47
0
        public virtual IDisposable Subscribe(ISubscriber subscriber, string cursor, Func<MessageResult, object, Task<bool>> callback, int maxMessages, object state)
        {
            if (subscriber == null)
            {
                throw new ArgumentNullException("subscriber");
            }

            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            Subscription subscription = CreateSubscription(subscriber, cursor, callback, maxMessages, state);

            // Set the subscription for this subscriber
            subscriber.Subscription = subscription;

            var topics = new HashSet<Topic>();

            foreach (var key in subscriber.EventKeys)
            {
                Topic topic = GetTopic(key);

                // Set the subscription for this topic
                subscription.SetEventTopic(key, topic);

                topics.Add(topic);
            }

            subscriber.EventKeyAdded += _addEvent;
            subscriber.EventKeyRemoved += _removeEvent;
            subscriber.WriteCursor = subscription.WriteCursor;

            // Add the subscription when it's all set and can be scheduled
            // for work
            foreach (var topic in topics)
            {
                topic.AddSubscription(subscription);
            }

            var disposable = new DisposableAction(_disposeSubscription, subscriber);

            // When the subscription itself is disposed then dispose it
            subscription.Disposable = disposable;

            // If there's a cursor then schedule work for this subscription
            if (!String.IsNullOrEmpty(cursor))
            {
                _broker.Schedule(subscription);
            }

            return disposable;
        }
Ejemplo n.º 48
0
        public void Execute(DocumentDatabase database)
        {
            docDb = database;


            docDb.Notifications.OnIndexChange += OnIndexChange;
            docDb.Notifications.OnTransformerChange += OnTransformerChange;

            var replicationRequestTimeoutInMs = docDb.Configuration.Replication.ReplicationRequestTimeoutInMilliseconds;

            autoTuner = new IndependentBatchSizeAutoTuner(docDb.WorkContext, PrefetchingUser.Replicator);
            httpRavenRequestFactory = new HttpRavenRequestFactory
            {
                RequestTimeoutInMs = replicationRequestTimeoutInMs
            };

            var task = new Task(Execute, TaskCreationOptions.LongRunning);
            var disposableAction = new DisposableAction(task.Wait);
            // make sure that the doc db waits for the replication task shutdown
            docDb.ExtensionsState.GetOrAdd(Guid.NewGuid().ToString(), s => disposableAction);

            _replicationFrequency = TimeSpan.FromSeconds(database.Configuration.IndexAndTransformerReplicationLatencyInSec); //by default 10 min
            _lastQueriedFrequency = TimeSpan.FromSeconds(database.Configuration.TimeToWaitBeforeRunningIdleIndexes.TotalSeconds / 2);

            _indexReplicationTaskTimer = database.TimerManager.NewTimer(x => ReplicateIndexesAndTransformersTask(x), TimeSpan.Zero, _replicationFrequency);
            _lastQueriedTaskTimer = database.TimerManager.NewTimer(SendLastQueriedTask, TimeSpan.Zero, _lastQueriedFrequency);

            task.Start();
        }
Ejemplo n.º 49
0
        public void ReceiveAbortBeforeCancellationSetup()
        {
            var response = new Mock<IResponse>();
            response.Setup(m => m.CancellationToken).Returns(CancellationToken.None);
            var request = new Mock<IRequest>();
            var qs = new NameValueCollection();
            qs["connectionId"] = "1";
            request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs));
            request.Setup(m => m.LocalPath).Returns("/test/echo/connect");
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = JsonUtility.CreateDefaultSerializer();
            var hostContext = new HostContext(request.Object, response.Object);
            var transportConnection = new Mock<ITransportConnection>();
            var traceManager = new Mock<ITraceManager>();
            counters.SetupGet(m => m.ConnectionsConnected).Returns(new NoOpPerformanceCounter());
            counters.SetupGet(m => m.ConnectionsDisconnected).Returns(new NoOpPerformanceCounter());
            traceManager.Setup(m => m[It.IsAny<string>()]).Returns(new System.Diagnostics.TraceSource("foo"));

            Func<PersistentResponse, object, Task<bool>> callback = null;
            object state = null;

            var disposable = new DisposableAction(() =>
            {
                callback(new PersistentResponse() { Terminal = true }, state);
            });

            transportConnection.Setup(m => m.Receive(It.IsAny<string>(),
                                                     It.IsAny<Func<PersistentResponse, object, Task<bool>>>(),
                                                     It.IsAny<int>(),
                                                     It.IsAny<object>())).Callback<string, Func<PersistentResponse, object, Task<bool>>, int, object>(async (id, cb, max, st) =>
                                                     {
                                                         callback = cb;
                                                         state = st;

                                                         bool result = await cb(new PersistentResponse() { Aborted = true } , st);

                                                         if (!result)
                                                         {
                                                             disposable.Dispose();
                                                         }
                                                     })
                                                    .Returns(disposable);
            transportConnection.Setup(m => m.Send(It.IsAny<ConnectionMessage>())).Returns(TaskAsyncHelper.Empty);

            var transport = new Mock<ForeverTransport>(hostContext, json, heartBeat.Object, counters.Object, traceManager.Object)
            {
                CallBase = true
            };

            transport.Setup(m => m.Send(It.IsAny<PersistentResponse>())).Returns(TaskAsyncHelper.Empty);

            bool ended = false;

            transport.Object.Connected = () => TaskAsyncHelper.Empty;

            transport.Object.AfterRequestEnd = (ex) =>
            {
                Assert.Null(ex);
                ended = true;
            };

            // Act
            transport.Object.ProcessRequest(transportConnection.Object);

            // Assert
            Assert.True(ended);
        }
Ejemplo n.º 50
0
        public void Execute(DocumentDatabase database)
        {
            docDb = database;
            _transactionalStorageId = docDb.TransactionalStorage.Id.ToString();

            var replicationRequestTimeoutInMs = docDb.Configuration.Replication.ReplicationRequestTimeoutInMilliseconds;

            autoTuner = new IndependentBatchSizeAutoTuner(docDb.WorkContext, PrefetchingUser.Replicator);
            httpRavenRequestFactory = new HttpRavenRequestFactory
            {
                RequestTimeoutInMs = replicationRequestTimeoutInMs
            };

            var task = new Task(Execute, TaskCreationOptions.LongRunning);
            var disposableAction = new DisposableAction(task.Wait);
            // make sure that the doc db waits for the replication task shutdown
            docDb.ExtensionsState.GetOrAdd(Guid.NewGuid().ToString(), s => disposableAction);

            IndexReplication = new IndexReplicationTask(database, httpRavenRequestFactory, this);
            TransformerReplication = new TransformerReplicationTask(database, httpRavenRequestFactory, this);

            task.Start();

            IndexReplication.Start();
            TransformerReplication.Start();
        }
Ejemplo n.º 51
0
		public void Execute(DocumentDatabase database)
		{
			docDb = database;
			var replicationRequestTimeoutInMs = docDb.Configuration.Replication.ReplicationRequestTimeoutInMilliseconds;
			
			autoTuner = new IndependentBatchSizeAutoTuner(docDb.WorkContext, PrefetchingUser.Replicator);
			httpRavenRequestFactory = new HttpRavenRequestFactory { RequestTimeoutInMs = replicationRequestTimeoutInMs };
			nonBufferedHttpRavenRequestFactory = new HttpRavenRequestFactory
			{
				RequestTimeoutInMs = replicationRequestTimeoutInMs,
				AllowWriteStreamBuffering = false
			};

            var task = new Task(Execute, TaskCreationOptions.LongRunning);
			var disposableAction = new DisposableAction(task.Wait);
			// make sure that the doc db waits for the replication task shutdown
			docDb.ExtensionsState.GetOrAdd(Guid.NewGuid().ToString(), s => disposableAction);
			task.Start();
		}
Ejemplo n.º 52
0
		public void Execute(DocumentDatabase database)
		{
			etagSynchronizer = database.EtagSynchronizer.GetSynchronizer(EtagSynchronizerType.Replicator);
			prefetchingBehavior = database.Prefetcher.GetPrefetchingBehavior(PrefetchingUser.Replicator, null);

			docDb = database;
			var replicationRequestTimeoutInMs =
				docDb.Configuration.GetConfigurationValue<int>("Raven/Replication/ReplicationRequestTimeout") ??
				60 * 1000;

			httpRavenRequestFactory = new HttpRavenRequestFactory { RequestTimeoutInMs = replicationRequestTimeoutInMs };

            var task = new Task(Execute, TaskCreationOptions.LongRunning);
			var disposableAction = new DisposableAction(task.Wait);
			// make sure that the doc db waits for the replication task shutdown
			docDb.ExtensionsState.GetOrAdd(Guid.NewGuid().ToString(), s => disposableAction);
			task.Start();
            

		}
Ejemplo n.º 53
0
        public void EnqueAsyncWriteAndEndRequest(Func<Task> writeAsync)
        {
            var response = new Mock<IResponse>();
            response.Setup(m => m.CancellationToken).Returns(CancellationToken.None);
            var request = new Mock<IRequest>();
            var qs = new NameValueCollection();
            qs["connectionId"] = "1";
            request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs));
            request.Setup(m => m.LocalPath).Returns("/test/echo/connect");
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = JsonUtility.CreateDefaultSerializer();
            var hostContext = new HostContext(request.Object, response.Object);
            var transportConnection = new Mock<ITransportConnection>();
            var traceManager = new Mock<ITraceManager>();
            counters.SetupGet(m => m.ConnectionsConnected).Returns(new NoOpPerformanceCounter());
            traceManager.Setup(m => m[It.IsAny<string>()]).Returns(new System.Diagnostics.TraceSource("foo"));

            Func<PersistentResponse, object, Task<bool>> callback = null;
            object state = null;

            var disposable = new DisposableAction(() =>
            {
                callback(new PersistentResponse() { Terminal = true }, state);
            });

            transportConnection.Setup(m => m.Receive(It.IsAny<string>(),
                                                     It.IsAny<Func<PersistentResponse, object, Task<bool>>>(),
                                                     It.IsAny<int>(),
                                                     It.IsAny<object>())).Callback<string, Func<PersistentResponse, object, Task<bool>>, int, object>((id, cb, max, st) =>
                                                     {
                                                         callback = cb;
                                                         state = st;
                                                     })
                                                     .Returns(disposable);
            transportConnection.Setup(m => m.Send(It.IsAny<ConnectionMessage>())).Returns(TaskAsyncHelper.Empty);

            var transport = new Mock<ForeverTransport>(hostContext, json, heartBeat.Object, counters.Object, traceManager.Object)
            {
                CallBase = true
            };

            transport.Setup(m => m.CancellationToken).Returns(CancellationToken.None);

            var tcs = new TaskCompletionSource<bool>();

            transport.Object.EnqueueOperation(writeAsync);

            transport.Object.Connected = () => TaskAsyncHelper.Empty;

            transport.Object.AfterRequestEnd = (ex) =>
            {
                // Trip the cancellation token
                tcs.TrySetResult(transport.Object.WriteQueue.IsDrained);
            };

            transport.Object.BeforeCancellationTokenCallbackRegistered = () =>
            {
                transport.Object.End();
            };

            Assert.True(transport.Object.ProcessRequest(transportConnection.Object).Wait(TimeSpan.FromSeconds(2)));
            Assert.True(tcs.Task.Result);
        }
Ejemplo n.º 54
0
        public virtual IDisposable Subscribe(ISubscriber subscriber, string cursor, Func<MessageResult, object, Task<bool>> callback, int maxMessages, object state)
        {
            if (subscriber == null)
            {
                throw new ArgumentNullException("subscriber");
            }

            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            Subscription subscription = CreateSubscription(subscriber, cursor, callback, maxMessages, state);

            // Set the subscription for this subscriber
            subscriber.Subscription = subscription;

            var topics = new HashSet<Topic>();

            foreach (var key in subscriber.EventKeys)
            {
                // Create or retrieve topic and set it as HasSubscriptions
                Topic topic = SubscribeTopic(key);

                // Set the subscription for this topic
                subscription.SetEventTopic(key, topic);

                topics.Add(topic);
            }

            subscriber.EventKeyAdded += _addEvent;
            subscriber.EventKeyRemoved += _removeEvent;
            subscriber.WriteCursor = subscription.WriteCursor;

            var subscriptionState = new SubscriptionState(subscriber);
            var disposable = new DisposableAction(_disposeSubscription, subscriptionState);

            // When the subscription itself is disposed then dispose it
            subscription.Disposable = disposable;

            // Add the subscription when it's all set and can be scheduled
            // for work. It's important to do this after everything is wired up for the
            // subscription so that publishes can schedule work at the right time.
            foreach (var topic in topics)
            {
                topic.AddSubscription(subscription);
            }

            subscriptionState.Initialized.Set();

            // If there's a cursor then schedule work for this subscription
            if (!String.IsNullOrEmpty(cursor))
            {
                _broker.Schedule(subscription);
            }

            return disposable;
        }
Ejemplo n.º 55
0
        public virtual IDisposable Subscribe(ISubscriber subscriber, string cursor, Func<MessageResult, Task<bool>> callback, int maxMessages)
        {
            Subscription subscription = CreateSubscription(subscriber, cursor, callback, maxMessages);

            var topics = new HashSet<Topic>();

            foreach (var key in subscriber.EventKeys)
            {
                Topic topic = GetTopic(key);

                // Set the subscription for this topic
                subscription.SetEventTopic(key, topic);

                topics.Add(topic);
            }

            Action<string> eventAdded = eventKey =>
            {
                Topic topic = GetTopic(eventKey);

                // Add or update the cursor (in case it already exists)
                subscription.AddEvent(eventKey, topic);

                // Add it to the list of subs
                topic.AddSubscription(subscription);
            };

            Action<string> eventRemoved = eventKey => RemoveEvent(subscription, eventKey);

            subscriber.EventKeyAdded += eventAdded;
            subscriber.EventKeyRemoved += eventRemoved;
            subscriber.GetCursor += subscription.GetCursor;

            // Add the subscription when it's all set and can be scheduled
            // for work
            foreach (var topic in topics)
            {
                topic.AddSubscription(subscription);
            }

            var disposable = new DisposableAction(() =>
            {
                // This will stop work from continuting to happen
                subscription.Dispose();

                try
                {
                    // Invoke the terminal callback
                    subscription.Invoke(MessageResult.TerminalMessage).Wait();
                }
                catch
                {
                    // We failed to talk to the subscriber because they are already gone
                    // so the terminal message isn't required.
                }

                subscriber.EventKeyAdded -= eventAdded;
                subscriber.EventKeyRemoved -= eventRemoved;
                subscriber.GetCursor -= subscription.GetCursor;

                foreach (var eventKey in subscriber.EventKeys)
                {
                    RemoveEvent(subscription, eventKey);
                }
            });

            // When the subscription itself is disposed then dispose it
            subscription.DisposedCallback = disposable.Dispose;

            // If there's a cursor then schedule work for this subscription
            if (!String.IsNullOrEmpty(cursor))
            {
                _broker.Schedule(subscription);
            }

            return disposable;
        }
Ejemplo n.º 56
0
        public void AvoidDeadlockIfCancellationTokenTriggeredBeforeSubscribing()
        {
            var testContext = new TestContext("/test/echo/connect");
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = JsonUtility.CreateDefaultSerializer();
            var transportConnection = new Mock<ITransportConnection>();
            var loggerFactory = new Mock<ILoggerFactory>();
            var memoryPool = new Mock<IMemoryPool>();
            counters.SetupGet(m => m.ConnectionsConnected).Returns(new NoOpPerformanceCounter());

            var applicationLifetime = new Mock<IApplicationLifetime>();
            applicationLifetime.SetupGet(m => m.ApplicationStopping).Returns(CancellationToken.None);

            var logger = new Mock<ILogger>();

            Func<PersistentResponse, object, Task<bool>> callback = null;
            object state = null;

            var disposable = new DisposableAction(() =>
            {
                callback(new PersistentResponse() { Terminal = true }, state);
            });

            transportConnection.Setup(m => m.Receive(It.IsAny<string>(),
                                                     It.IsAny<Func<PersistentResponse, object, Task<bool>>>(),
                                                     It.IsAny<int>(),
                                                     It.IsAny<object>())).Callback<string, Func<PersistentResponse, object, Task<bool>>, int, object>((id, cb, max, st) =>
                                                     {
                                                         callback = cb;
                                                         state = st;
                                                     })
                                                     .Returns(disposable);

            var transport = new Mock<ForeverTransport>(testContext.MockHttpContext.Object, json, heartBeat.Object, counters.Object, applicationLifetime.Object, loggerFactory.Object, memoryPool.Object)
            {
                CallBase = true
            };

            var wh = new ManualResetEventSlim();

            transport.Object.BeforeCancellationTokenCallbackRegistered = () =>
            {
                // Trip the cancellation token
                transport.Object.End();
            };

            // Act
            Task.Factory.StartNew(() =>
            {
                transport.Object.ProcessRequest(transportConnection.Object);
                wh.Set();
            });

            Assert.True(wh.Wait(TimeSpan.FromSeconds(2)), "Dead lock!");
        }
Ejemplo n.º 57
0
		/// <summary>
		/// Initializes a new instance of the <see cref="DefaultRavenContractResolver"/> class.
		/// </summary>
		/// <param name="shareCache">If set to <c>true</c> the <see cref="T:Raven.Imports.Newtonsoft.Json.Serialization.DefaultContractResolver"/> will use a cached shared with other resolvers of the same type.
		/// Sharing the cache will significantly performance because expensive reflection will only happen once but could cause unexpected
		/// behavior if different instances of the resolver are suppose to produce different results. When set to false it is highly
		/// recommended to reuse <see cref="T:Raven.Imports.Newtonsoft.Json.Serialization.DefaultContractResolver"/> instances with the <see cref="T:Raven.Imports.Newtonsoft.Json.JsonSerializer"/>.</param>
		public DefaultRavenContractResolver(bool shareCache) : base(shareCache)
		{
			clearExtensionData = new DisposableAction(() => currentExtensionData = null);
		}
Ejemplo n.º 58
0
        public void EnqueAsyncWriteAndEndRequest(Func<Task> writeAsync)
        {
            var testContext = new TestContext("/test/echo/connect");
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = JsonUtility.CreateDefaultSerializer();
            var transportConnection = new Mock<ITransportConnection>();
            var loggerFactory = new Mock<ILoggerFactory>();
            var memoryPool = new Mock<IMemoryPool>();

            counters.SetupGet(m => m.ConnectionsConnected).Returns(new NoOpPerformanceCounter());

            var logger = new Mock<ILogger>();
            loggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(logger.Object);

            Func<PersistentResponse, object, Task<bool>> callback = null;
            object state = null;

            var disposable = new DisposableAction(() =>
            {
                callback(new PersistentResponse() { Terminal = true }, state);
            });

            var applicationLifetime = new Mock<IApplicationLifetime>();
            applicationLifetime.SetupGet(m => m.ApplicationStopping).Returns(CancellationToken.None);

            transportConnection.Setup(m => m.Receive(It.IsAny<string>(),
                                                     It.IsAny<Func<PersistentResponse, object, Task<bool>>>(),
                                                     It.IsAny<int>(),
                                                     It.IsAny<object>())).Callback<string, Func<PersistentResponse, object, Task<bool>>, int, object>((id, cb, max, st) =>
                                                     {
                                                         callback = cb;
                                                         state = st;
                                                     })
                                                     .Returns(disposable);
            transportConnection.Setup(m => m.Send(It.IsAny<ConnectionMessage>())).Returns(TaskAsyncHelper.Empty);

            var transport = new Mock<ForeverTransport>(testContext.MockHttpContext.Object, json, heartBeat.Object, counters.Object, applicationLifetime.Object, loggerFactory.Object, memoryPool.Object)
            {
                CallBase = true
            };

            transport.Setup(m => m.CancellationToken).Returns(CancellationToken.None);

            var tcs = new TaskCompletionSource<bool>();

            transport.Object.EnqueueOperation(writeAsync);

            transport.Object.Connected = () => TaskAsyncHelper.Empty;

            transport.Object.AfterRequestEnd = (ex) =>
            {
                // Trip the cancellation token
                tcs.TrySetResult(transport.Object.WriteQueue.IsDrained);
            };

            transport.Object.BeforeCancellationTokenCallbackRegistered = () =>
            {
                transport.Object.End();
            };

            Assert.True(transport.Object.ProcessRequest(transportConnection.Object).Wait(TimeSpan.FromSeconds(10)));
            Assert.True(tcs.Task.Result);
        }
Ejemplo n.º 59
0
        public void ReceiveDisconnectBeforeCancellationSetup()
        {
            var testContext = new TestContext("/test/echo/connect");
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = JsonUtility.CreateDefaultSerializer();
            var transportConnection = new Mock<ITransportConnection>();
            var loggerFactory = new Mock<ILoggerFactory>();
            var memoryPool = new Mock<IMemoryPool>();
            counters.SetupGet(m => m.ConnectionsConnected).Returns(new NoOpPerformanceCounter());
            counters.SetupGet(m => m.ConnectionsDisconnected).Returns(new NoOpPerformanceCounter());

            var applicationLifetime = new Mock<IApplicationLifetime>();
            applicationLifetime.SetupGet(m => m.ApplicationStopping).Returns(CancellationToken.None);

            var logger = new Mock<ILogger>();
            loggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(logger.Object);

            Func<PersistentResponse, object, Task<bool>> callback = null;
            object state = null;

            var disposable = new DisposableAction(() =>
            {
                callback(new PersistentResponse() { Terminal = true }, state);
            });

            transportConnection.Setup(m => m.Receive(It.IsAny<string>(),
                                                     It.IsAny<Func<PersistentResponse, object, Task<bool>>>(),
                                                     It.IsAny<int>(),
                                                     It.IsAny<object>())).Callback<string, Func<PersistentResponse, object, Task<bool>>, int, object>(async (id, cb, max, st) =>
                                                     {
                                                         callback = cb;
                                                         state = st;

                                                         bool result = await cb(new PersistentResponse() { Aborted = true }, st);

                                                         if (!result)
                                                         {
                                                             disposable.Dispose();
                                                         }
                                                     })
                                                    .Returns(disposable);
            transportConnection.Setup(m => m.Send(It.IsAny<ConnectionMessage>())).Returns(TaskAsyncHelper.Empty);

            var transport = new Mock<ForeverTransport>(testContext.MockHttpContext.Object, json, heartBeat.Object, counters.Object, applicationLifetime.Object, loggerFactory.Object, memoryPool.Object)
            {
                CallBase = true
            };

            transport.Setup(m => m.Send(It.IsAny<PersistentResponse>())).Returns(TaskAsyncHelper.Empty);

            bool ended = false;

            transport.Object.Connected = () => TaskAsyncHelper.Empty;

            transport.Object.AfterRequestEnd = (ex) =>
            {
                Assert.Null(ex);
                ended = true;
            };

            // Act
            transport.Object.ProcessRequest(transportConnection.Object);

            // Assert
            Assert.True(ended);
        }
Ejemplo n.º 60
0
		public IDisposable EnterWriteLock()
		{
			var release = new DisposableAction(() => Monitor.Exit(inner));
			Monitor.Enter(inner);
			return release;
		}