Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/rx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Rx.NET/System.Reactive.Core/Reactive/Concurrency/AsyncLock.cs')
-rw-r--r--Rx.NET/System.Reactive.Core/Reactive/Concurrency/AsyncLock.cs84
1 files changed, 84 insertions, 0 deletions
diff --git a/Rx.NET/System.Reactive.Core/Reactive/Concurrency/AsyncLock.cs b/Rx.NET/System.Reactive.Core/Reactive/Concurrency/AsyncLock.cs
new file mode 100644
index 0000000..73def1a
--- /dev/null
+++ b/Rx.NET/System.Reactive.Core/Reactive/Concurrency/AsyncLock.cs
@@ -0,0 +1,84 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+
+namespace System.Reactive.Concurrency
+{
+ /// <summary>
+ /// Asynchronous lock.
+ /// </summary>
+ public sealed class AsyncLock : IDisposable
+ {
+ private readonly Queue<Action> queue = new Queue<Action>();
+ private bool isAcquired = false;
+ private bool hasFaulted = false;
+
+ /// <summary>
+ /// Queues the action for execution. If the caller acquires the lock and becomes the owner,
+ /// the queue is processed. If the lock is already owned, the action is queued and will get
+ /// processed by the owner.
+ /// </summary>
+ /// <param name="action">Action to queue for execution.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
+ public void Wait(Action action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+
+ var isOwner = false;
+ lock (queue)
+ {
+ if (!hasFaulted)
+ {
+ queue.Enqueue(action);
+ isOwner = !isAcquired;
+ isAcquired = true;
+ }
+ }
+
+ if (isOwner)
+ {
+ while (true)
+ {
+ var work = default(Action);
+ lock (queue)
+ {
+ if (queue.Count > 0)
+ work = queue.Dequeue();
+ else
+ {
+ isAcquired = false;
+ break;
+ }
+ }
+
+ try
+ {
+ work();
+ }
+ catch
+ {
+ lock (queue)
+ {
+ queue.Clear();
+ hasFaulted = true;
+ }
+ throw;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Clears the work items in the queue and drops further work being queued.
+ /// </summary>
+ public void Dispose()
+ {
+ lock (queue)
+ {
+ queue.Clear();
+ hasFaulted = true;
+ }
+ }
+ }
+}