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/Tests.System.Reactive/Semaphore.cs')
-rw-r--r--Rx.NET/Tests.System.Reactive/Semaphore.cs116
1 files changed, 116 insertions, 0 deletions
diff --git a/Rx.NET/Tests.System.Reactive/Semaphore.cs b/Rx.NET/Tests.System.Reactive/Semaphore.cs
new file mode 100644
index 0000000..471672c
--- /dev/null
+++ b/Rx.NET/Tests.System.Reactive/Semaphore.cs
@@ -0,0 +1,116 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+
+#if SILVERLIGHT
+using System;
+
+namespace System.Threading
+{
+ //Monitor based implementation of Semaphore
+ //that mimicks the .NET Semaphore class (System.Threading.Semaphore)
+
+ internal sealed class Semaphore : IDisposable
+ {
+ private int m_currentCount;
+ private int m_maximumCount;
+ private object m_lockObject;
+ private bool m_disposed;
+
+ public Semaphore(int initialCount, int maximumCount)
+ {
+ if (initialCount < 0)
+ {
+ throw new ArgumentOutOfRangeException("initialCount", "Non-negative number required.");
+ }
+ if (maximumCount < 1)
+ {
+ throw new ArgumentOutOfRangeException("maximumCount", "Positive number required.");
+ }
+ if (initialCount > maximumCount)
+ {
+ throw new ArgumentException("Initial count must be smaller than maximum");
+ }
+
+ m_currentCount = initialCount;
+ m_maximumCount = maximumCount;
+ m_lockObject = new object();
+ }
+
+ public int Release()
+ {
+ return this.Release(1);
+ }
+
+ public int Release(int releaseCount)
+ {
+ if (releaseCount < 1)
+ {
+ throw new ArgumentOutOfRangeException("releaseCount", "Positive number required.");
+ }
+ if (m_disposed)
+ {
+ throw new ObjectDisposedException("Semaphore");
+ }
+
+ var oldCount = default(int);
+ lock (m_lockObject)
+ {
+ oldCount = m_currentCount;
+ if (releaseCount + m_currentCount > m_maximumCount)
+ {
+ throw new ArgumentOutOfRangeException("releaseCount", "Amount of releases would overflow maximum");
+ }
+ m_currentCount += releaseCount;
+ //PulseAll makes sure all waiting threads get queued for acquiring the lock
+ //Pulse would only queue one thread.
+
+ Monitor.PulseAll(m_lockObject);
+ }
+ return oldCount;
+ }
+
+ public bool WaitOne()
+ {
+ return WaitOne(Timeout.Infinite);
+ }
+
+ public bool WaitOne(int millisecondsTimeout)
+ {
+ if (m_disposed)
+ {
+ throw new ObjectDisposedException("Semaphore");
+ }
+
+ lock (m_lockObject)
+ {
+ while (m_currentCount == 0)
+ {
+ if (!Monitor.Wait(m_lockObject, millisecondsTimeout))
+ {
+ return false;
+ }
+ }
+ m_currentCount--;
+ return true;
+ }
+ }
+
+ public bool WaitOne(TimeSpan timeout)
+ {
+ return WaitOne((int)timeout.TotalMilliseconds);
+ }
+
+ public void Close()
+ {
+ Dispose();
+ }
+
+ public void Dispose()
+ {
+ //the .NET CLR semaphore does not release waits upon dispose
+ //so we don't do that either.
+ m_disposed = true;
+ m_lockObject = null;
+ }
+ }
+}
+#endif \ No newline at end of file