Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -1,101 +0,0 @@
//
// System.Threading.AbandonedMutexException.cs
//
// Author:
// Dick Porter (dick@ximian.com)
//
// (C) Ximian, Inc. http://www.ximian.com
//
//
// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
namespace System.Threading
{
[Serializable]
[ComVisible (false)]
public class AbandonedMutexException : SystemException
{
Mutex mutex;
int mutex_index = -1;
public AbandonedMutexException()
: base ("Mutex was abandoned")
{
}
public AbandonedMutexException (string message)
: base (message)
{
}
public AbandonedMutexException (int location, WaitHandle handle)
: base ("Mutex was abandoned")
{
mutex_index = location;
mutex = handle as Mutex;
}
protected AbandonedMutexException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
}
public AbandonedMutexException (string message, Exception inner)
: base (message, inner)
{
}
public AbandonedMutexException (string message, int location, WaitHandle handle)
: base (message)
{
mutex_index = location;
mutex = handle as Mutex;
}
public AbandonedMutexException (string message, Exception inner, int location, WaitHandle handle)
: base (message, inner)
{
mutex_index = location;
mutex = handle as Mutex;
}
public Mutex Mutex
{
get {
return(mutex);
}
}
public int MutexIndex
{
get {
return(mutex_index);
}
}
}
}

View File

@@ -1,44 +0,0 @@
//
// System.Threading.ApartmentState.cs
//
// Author:
// Dick Porter (dick@ximian.com)
//
// (C) Ximian, Inc. http://www.ximian.com
//
//
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Runtime.InteropServices;
namespace System.Threading
{
[ComVisible (true)]
[Serializable]
public enum ApartmentState {
STA = 0,
MTA = 1,
Unknown = 2
}
}

View File

@@ -65,11 +65,7 @@ namespace System.Threading {
_t = null;
}
#if NET_4_0
public void Dispose ()
#else
void IDisposable.Dispose ()
#endif
{
if (_t != null) {
Undo ();

View File

@@ -1,186 +0,0 @@
// AtomicBoolean.cs
//
// Copyright (c) 2008 Jérémie "Garuma" Laval
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
using System;
#if INSIDE_MONO_PARALLEL
using System.Threading;
namespace Mono.Threading
#else
namespace System.Threading
#endif
{
#if INSIDE_MONO_PARALLEL
public
#endif
struct AtomicBooleanValue
{
int flag;
const int UnSet = 0;
const int Set = 1;
public bool CompareAndExchange (bool expected, bool newVal)
{
int newTemp = newVal ? Set : UnSet;
int expectedTemp = expected ? Set : UnSet;
return Interlocked.CompareExchange (ref flag, newTemp, expectedTemp) == expectedTemp;
}
public static AtomicBooleanValue FromValue (bool value)
{
AtomicBooleanValue temp = new AtomicBooleanValue ();
temp.Value = value;
return temp;
}
public bool TrySet ()
{
return !Exchange (true);
}
public bool TryRelaxedSet ()
{
return flag == UnSet && !Exchange (true);
}
public bool Exchange (bool newVal)
{
int newTemp = newVal ? Set : UnSet;
return Interlocked.Exchange (ref flag, newTemp) == Set;
}
public bool Value {
get {
return flag == Set;
}
set {
Exchange (value);
}
}
public bool Equals (AtomicBooleanValue rhs)
{
return this.flag == rhs.flag;
}
public override bool Equals (object rhs)
{
return rhs is AtomicBooleanValue ? Equals ((AtomicBooleanValue)rhs) : false;
}
public override int GetHashCode ()
{
return flag.GetHashCode ();
}
public static explicit operator bool (AtomicBooleanValue rhs)
{
return rhs.Value;
}
public static implicit operator AtomicBooleanValue (bool rhs)
{
return AtomicBooleanValue.FromValue (rhs);
}
}
#if INSIDE_MONO_PARALLEL
public
#endif
class AtomicBoolean
{
int flag;
const int UnSet = 0;
const int Set = 1;
public bool CompareAndExchange (bool expected, bool newVal)
{
int newTemp = newVal ? Set : UnSet;
int expectedTemp = expected ? Set : UnSet;
return Interlocked.CompareExchange (ref flag, newTemp, expectedTemp) == expectedTemp;
}
public static AtomicBoolean FromValue (bool value)
{
AtomicBoolean temp = new AtomicBoolean ();
temp.Value = value;
return temp;
}
public bool TrySet ()
{
return !Exchange (true);
}
public bool TryRelaxedSet ()
{
return flag == UnSet && !Exchange (true);
}
public bool Exchange (bool newVal)
{
int newTemp = newVal ? Set : UnSet;
return Interlocked.Exchange (ref flag, newTemp) == Set;
}
public bool Value {
get {
return flag == Set;
}
set {
Exchange (value);
}
}
public bool Equals (AtomicBoolean rhs)
{
return this.flag == rhs.flag;
}
public override bool Equals (object rhs)
{
return rhs is AtomicBoolean ? Equals ((AtomicBoolean)rhs) : false;
}
public override int GetHashCode ()
{
return flag.GetHashCode ();
}
public static explicit operator bool (AtomicBoolean rhs)
{
return rhs.Value;
}
public static implicit operator AtomicBoolean (bool rhs)
{
return AtomicBoolean.FromValue (rhs);
}
}
}

View File

@@ -1,49 +0,0 @@
//
// System.Threading.AutoResetEvent.cs
//
// Author:
// Dick Porter (dick@ximian.com)
// Veronica De Santis (veron78@interfree.it)
//
// (C) Ximian, Inc. http://www.ximian.com
//
//
// Copyright (C) 2004, 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System.Threading
{
[ComVisible (true)]
public sealed class AutoResetEvent : EventWaitHandle
{
// Constructor
public AutoResetEvent (bool initialState)
: base(initialState, EventResetMode.AutoReset)
{
}
}
}

View File

@@ -1,142 +0,0 @@
//
// CancellationToken.cs
//
// Authors:
// Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
// Marek Safar (marek.safar@gmail.com)
//
// Copyright (c) 2009 Jérémie "Garuma" Laval
// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if NET_4_0
using System;
using System.Threading;
using System.Diagnostics;
namespace System.Threading
{
[DebuggerDisplay ("IsCancellationRequested = {IsCancellationRequested}")]
public struct CancellationToken
{
readonly CancellationTokenSource source;
public CancellationToken (bool canceled)
: this (canceled ? CancellationTokenSource.CanceledSource : null)
{
}
internal CancellationToken (CancellationTokenSource source)
{
this.source = source;
}
public static CancellationToken None {
get {
// simply return new struct value, it's the fastest option
// and we don't have to bother with reseting source
return new CancellationToken ();
}
}
public CancellationTokenRegistration Register (Action callback)
{
return Register (callback, false);
}
public CancellationTokenRegistration Register (Action callback, bool useSynchronizationContext)
{
if (callback == null)
throw new ArgumentNullException ("callback");
return Source.Register (callback, useSynchronizationContext);
}
public CancellationTokenRegistration Register (Action<object> callback, object state)
{
return Register (callback, state, false);
}
public CancellationTokenRegistration Register (Action<object> callback, object state, bool useSynchronizationContext)
{
if (callback == null)
throw new ArgumentNullException ("callback");
return Register (() => callback (state), useSynchronizationContext);
}
public void ThrowIfCancellationRequested ()
{
if (source != null && source.IsCancellationRequested)
throw new OperationCanceledException (this);
}
public bool Equals (CancellationToken other)
{
return this.Source == other.Source;
}
public override bool Equals (object other)
{
return (other is CancellationToken) ? Equals ((CancellationToken)other) : false;
}
public override int GetHashCode ()
{
return Source.GetHashCode ();
}
public static bool operator == (CancellationToken left, CancellationToken right)
{
return left.Equals (right);
}
public static bool operator != (CancellationToken left, CancellationToken right)
{
return !left.Equals (right);
}
public bool CanBeCanceled {
get {
return source != null;
}
}
public bool IsCancellationRequested {
get {
return Source.IsCancellationRequested;
}
}
public WaitHandle WaitHandle {
get {
return Source.WaitHandle;
}
}
CancellationTokenSource Source {
get {
return source ?? CancellationTokenSource.NoneSource;
}
}
}
}
#endif

View File

@@ -1,79 +0,0 @@
//
// CancellationTokenRegistration.cs
//
// Author:
// Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
//
// Copyright (c) 2009 Jérémie "Garuma" Laval
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if NET_4_0
using System;
namespace System.Threading
{
public struct CancellationTokenRegistration: IDisposable, IEquatable<CancellationTokenRegistration>
{
readonly int id;
readonly CancellationTokenSource source;
internal CancellationTokenRegistration (int id, CancellationTokenSource source)
{
this.id = id;
this.source = source;
}
#region IDisposable implementation
public void Dispose ()
{
if (source != null)
source.RemoveCallback (this);
}
#endregion
#region IEquatable<CancellationTokenRegistration> implementation
public bool Equals (CancellationTokenRegistration other)
{
return id == other.id && source == other.source;
}
public static bool operator== (CancellationTokenRegistration left, CancellationTokenRegistration right)
{
return left.Equals (right);
}
public static bool operator!= (CancellationTokenRegistration left, CancellationTokenRegistration right)
{
return !left.Equals (right);
}
#endregion
public override int GetHashCode ()
{
return id.GetHashCode () ^ (source == null ? 0 : source.GetHashCode ());
}
public override bool Equals (object obj)
{
return (obj is CancellationTokenRegistration) && Equals ((CancellationTokenRegistration)obj);
}
}
}
#endif

View File

@@ -1,322 +0,0 @@
//
// CancellationTokenSource.cs
//
// Authors:
// Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
// Marek Safar (marek.safar@gmail.com)
//
// Copyright (c) 2009 Jérémie "Garuma" Laval
// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if NET_4_0
using System.Collections.Generic;
using System.Collections.Concurrent;
namespace System.Threading
{
#if !NET_4_5
sealed
#endif
public class CancellationTokenSource : IDisposable
{
const int StateValid = 0;
const int StateCanceled = 1 << 1;
const int StateDisposed = 1 << 2;
int state;
int currId = int.MinValue;
ConcurrentDictionary<CancellationTokenRegistration, Action> callbacks;
CancellationTokenRegistration[] linkedTokens;
ManualResetEvent handle;
internal static readonly CancellationTokenSource NoneSource = new CancellationTokenSource ();
internal static readonly CancellationTokenSource CanceledSource = new CancellationTokenSource ();
#if NET_4_5
static readonly TimerCallback timer_callback;
Timer timer;
#endif
static CancellationTokenSource ()
{
CanceledSource.state = StateCanceled;
#if NET_4_5
timer_callback = token => {
var cts = (CancellationTokenSource) token;
cts.CancelSafe ();
};
#endif
}
public CancellationTokenSource ()
{
callbacks = new ConcurrentDictionary<CancellationTokenRegistration, Action> ();
handle = new ManualResetEvent (false);
}
#if NET_4_5
public CancellationTokenSource (int millisecondsDelay)
: this ()
{
if (millisecondsDelay < -1)
throw new ArgumentOutOfRangeException ("millisecondsDelay");
if (millisecondsDelay != Timeout.Infinite)
timer = new Timer (timer_callback, this, millisecondsDelay, Timeout.Infinite);
}
public CancellationTokenSource (TimeSpan delay)
: this (CheckTimeout (delay))
{
}
#endif
public CancellationToken Token {
get {
CheckDisposed ();
return new CancellationToken (this);
}
}
public bool IsCancellationRequested {
get {
return (state & StateCanceled) != 0;
}
}
internal WaitHandle WaitHandle {
get {
CheckDisposed ();
return handle;
}
}
public void Cancel ()
{
Cancel (false);
}
// If parameter is true we throw exception as soon as they appear otherwise we aggregate them
public void Cancel (bool throwOnFirstException)
{
CheckDisposed ();
Cancellation (throwOnFirstException);
}
//
// Don't throw ObjectDisposedException if the callback
// is called concurrently with a Dispose
//
void CancelSafe ()
{
if (state == StateValid)
Cancellation (true);
}
void Cancellation (bool throwOnFirstException)
{
if (Interlocked.CompareExchange (ref state, StateCanceled, StateValid) != StateValid)
return;
handle.Set ();
if (linkedTokens != null)
UnregisterLinkedTokens ();
var cbs = callbacks;
if (cbs == null)
return;
List<Exception> exceptions = null;
try {
Action cb;
for (int id = currId; id != int.MinValue; id--) {
if (!cbs.TryRemove (new CancellationTokenRegistration (id, this), out cb))
continue;
if (cb == null)
continue;
if (throwOnFirstException) {
cb ();
} else {
try {
cb ();
} catch (Exception e) {
if (exceptions == null)
exceptions = new List<Exception> ();
exceptions.Add (e);
}
}
}
} finally {
cbs.Clear ();
}
if (exceptions != null)
throw new AggregateException (exceptions);
}
#if NET_4_5
public void CancelAfter (TimeSpan delay)
{
CancelAfter (CheckTimeout (delay));
}
public void CancelAfter (int millisecondsDelay)
{
if (millisecondsDelay < -1)
throw new ArgumentOutOfRangeException ("millisecondsDelay");
CheckDisposed ();
if (IsCancellationRequested || millisecondsDelay == Timeout.Infinite)
return;
if (timer == null) {
// Have to be carefull not to create secondary background timer
var t = new Timer (timer_callback, this, Timeout.Infinite, Timeout.Infinite);
if (Interlocked.CompareExchange (ref timer, t, null) != null)
t.Dispose ();
}
timer.Change (millisecondsDelay, Timeout.Infinite);
}
#endif
public static CancellationTokenSource CreateLinkedTokenSource (CancellationToken token1, CancellationToken token2)
{
return CreateLinkedTokenSource (new [] { token1, token2 });
}
public static CancellationTokenSource CreateLinkedTokenSource (params CancellationToken[] tokens)
{
if (tokens == null)
throw new ArgumentNullException ("tokens");
if (tokens.Length == 0)
throw new ArgumentException ("Empty tokens array");
CancellationTokenSource src = new CancellationTokenSource ();
Action action = src.CancelSafe;
var registrations = new List<CancellationTokenRegistration> (tokens.Length);
foreach (CancellationToken token in tokens) {
if (token.CanBeCanceled)
registrations.Add (token.Register (action));
}
src.linkedTokens = registrations.ToArray ();
return src;
}
static int CheckTimeout (TimeSpan delay)
{
try {
return checked ((int) delay.TotalMilliseconds);
} catch (OverflowException) {
throw new ArgumentOutOfRangeException ("delay");
}
}
void CheckDisposed ()
{
if ((state & StateDisposed) != 0)
throw new ObjectDisposedException (GetType ().Name);
}
public void Dispose ()
{
Dispose (true);
}
#if NET_4_5
protected virtual
#endif
void Dispose (bool disposing)
{
if (disposing && (state & StateDisposed) == 0) {
if (Interlocked.CompareExchange (ref state, StateDisposed, StateValid) == StateValid) {
UnregisterLinkedTokens ();
callbacks = null;
} else {
if (handle != null)
handle.WaitOne ();
state |= StateDisposed;
Thread.MemoryBarrier ();
}
#if NET_4_5
if (timer != null)
timer.Dispose ();
#endif
handle.Dispose ();
handle = null;
}
}
void UnregisterLinkedTokens ()
{
var registrations = Interlocked.Exchange (ref linkedTokens, null);
if (registrations == null)
return;
foreach (var linked in registrations)
linked.Dispose ();
}
internal CancellationTokenRegistration Register (Action callback, bool useSynchronizationContext)
{
CheckDisposed ();
var tokenReg = new CancellationTokenRegistration (Interlocked.Increment (ref currId), this);
/* If the source is already canceled we execute the callback immediately
* if not, we try to add it to the queue and if it is currently being processed
* we try to execute it back ourselves to be sure the callback is ran
*/
if (IsCancellationRequested)
callback ();
else {
callbacks.TryAdd (tokenReg, callback);
if (IsCancellationRequested && callbacks.TryRemove (tokenReg, out callback))
callback ();
}
return tokenReg;
}
internal void RemoveCallback (CancellationTokenRegistration reg)
{
// Ignore call if the source has been disposed
if ((state & StateDisposed) != 0)
return;
Action dummy;
var cbs = callbacks;
if (cbs != null)
cbs.TryRemove (reg, out dummy);
}
}
}
#endif

View File

@@ -76,12 +76,7 @@ namespace System.Threading {
// NOTE: This method doesn't show in the class library status page because
// it cannot be "found" with the StrongNameIdentityPermission for ECMA key.
// But it's there!
#if NET_4_0
[SecurityCritical]
#else
[SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
[StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey="00000000000000000400000000000000")]
#endif
static public CompressedStack GetCompressedStack ()
{
// Note: CompressedStack.GetCompressedStack doesn't return null
@@ -101,22 +96,14 @@ namespace System.Threading {
}
[MonoTODO ("incomplete")]
#if NET_4_0
[SecurityCritical]
#else
[ReflectionPermission (SecurityAction.Demand, MemberAccess = true)]
#endif
public void GetObjectData (SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException ("info");
}
#if NET_4_0
[SecurityCritical]
#else
[SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
#endif
static public void Run (CompressedStack compressedStack, ContextCallback callback, object state)
{
if (compressedStack == null)

View File

@@ -1,211 +0,0 @@
// CountdownEvent.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (c) 2008 Jérémie "Garuma" Laval
// Copyright 2011 Xamarin Inc (http://www.xamarin.com).
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
#if NET_4_0
namespace System.Threading
{
[System.Diagnostics.DebuggerDisplayAttribute ("Initial Count={InitialCount}, Current Count={CurrentCount}")]
public class CountdownEvent : IDisposable
{
int initialCount;
int initial;
ManualResetEventSlim evt;
public CountdownEvent (int initialCount)
{
if (initialCount < 0)
throw new ArgumentOutOfRangeException ("initialCount");
evt = new ManualResetEventSlim (initialCount == 0);
this.initial = this.initialCount = initialCount;
}
public int CurrentCount {
get {
return initialCount;
}
}
public int InitialCount {
get {
return initial;
}
}
public bool IsSet {
get {
return initialCount == 0;
}
}
public WaitHandle WaitHandle {
get {
return evt.WaitHandle;
}
}
public bool Signal ()
{
return Signal (1);
}
public bool Signal (int signalCount)
{
if (signalCount <= 0)
throw new ArgumentOutOfRangeException ("signalCount");
CheckDisposed ();
int newValue;
if (!ApplyOperation (-signalCount, out newValue))
throw new InvalidOperationException ("The event is already set");
if (newValue == 0) {
evt.Set ();
return true;
}
return false;
}
public void AddCount ()
{
AddCount (1);
}
public void AddCount (int signalCount)
{
if (!TryAddCount (signalCount))
throw new InvalidOperationException ("The event is already signaled and cannot be incremented");
}
public bool TryAddCount ()
{
return TryAddCount (1);
}
public bool TryAddCount (int signalCount)
{
if (signalCount <= 0)
throw new ArgumentOutOfRangeException ("signalCount");
CheckDisposed ();
int temp;
return ApplyOperation (signalCount, out temp);
}
bool ApplyOperation (int num, out int newValue)
{
int oldCount;
do {
oldCount = initialCount;
if (oldCount == 0) {
newValue = 0;
return false;
}
newValue = oldCount + num;
if (newValue < 0)
return false;
} while (Interlocked.CompareExchange (ref initialCount, newValue, oldCount) != oldCount);
return true;
}
public void Wait ()
{
evt.Wait ();
}
public void Wait (CancellationToken cancellationToken)
{
evt.Wait (cancellationToken);
}
public bool Wait (int millisecondsTimeout)
{
return evt.Wait (millisecondsTimeout);
}
public bool Wait(TimeSpan timeout)
{
return evt.Wait (timeout);
}
public bool Wait (int millisecondsTimeout, CancellationToken cancellationToken)
{
return evt.Wait (millisecondsTimeout, cancellationToken);
}
public bool Wait(TimeSpan timeout, CancellationToken cancellationToken)
{
return evt.Wait (timeout, cancellationToken);
}
public void Reset ()
{
Reset (initial);
}
public void Reset (int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException ("count");
CheckDisposed ();
initialCount = initial = count;
if (count == 0)
evt.Set ();
else
evt.Reset ();
}
public void Dispose ()
{
Dispose (true);
}
protected virtual void Dispose (bool disposing)
{
if (disposing)
evt.Dispose ();
}
void CheckDisposed ()
{
if (evt.disposed.Value)
throw new ObjectDisposedException ("CountdownEvent");
}
}
}
#endif

View File

@@ -1,42 +0,0 @@
// EventResetMode.cs
//
// Author:
// Dick Porter (dick@ximian.com)
//
// (C) Ximian, Inc. http://www.ximian.com
//
//
// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Runtime.InteropServices;
namespace System.Threading
{
[ComVisible (false)]
public enum EventResetMode
{
AutoReset = 0,
ManualReset = 1,
}
}

View File

@@ -38,11 +38,44 @@ using System.Collections.Generic;
namespace System.Threading {
[Serializable]
public sealed class ExecutionContext : ISerializable
#if NET_4_0
, IDisposable
#endif
public sealed partial class ExecutionContext : ISerializable
, IDisposable
{
internal struct Switcher
{
readonly ExecutionContext ec;
readonly LogicalCallContext _lcc;
readonly bool _suppressFlow;
readonly bool _capture;
readonly Dictionary<string, object> local_data;
readonly bool copy_on_write;
public Switcher (ExecutionContext ec)
{
this.ec = ec;
this._lcc = ec._lcc;
this._suppressFlow = ec._suppressFlow;
this._capture = ec._capture;
this.local_data = ec.local_data;
this.copy_on_write = ec.CopyOnWrite;
}
public bool IsEmpty {
get {
return ec == null;
}
}
public void Restore (ExecutionContext ec)
{
ec._lcc = this._lcc;
ec._suppressFlow = this._suppressFlow;
ec._capture = this._capture;
ec.local_data = this.local_data;
ec.CopyOnWrite = this.copy_on_write;
}
}
#if !MOBILE
private SecurityContext _sc;
#endif
@@ -57,15 +90,20 @@ namespace System.Threading {
private ExecutionContext (ExecutionContext ec)
{
CloneData (ec);
_suppressFlow = ec._suppressFlow;
_capture = true;
}
void CloneData (ExecutionContext ec)
{
#if !MOBILE
if (ec._sc != null)
_sc = new SecurityContext (ec._sc);
#endif
if (ec._lcc != null)
_lcc = (LogicalCallContext) ec._lcc.Clone ();
_suppressFlow = ec._suppressFlow;
_capture = true;
}
[MonoTODO]
@@ -81,7 +119,11 @@ namespace System.Threading {
internal static ExecutionContext Capture (bool captureSyncContext, bool nullOnEmpty)
{
ExecutionContext ec = Current;
var thread = Thread.CurrentThread;
if (nullOnEmpty && !thread.HasExecutionContext)
return null;
var ec = thread.ExecutionContext;
if (ec.FlowSuppressed)
return null;
@@ -108,7 +150,6 @@ namespace System.Threading {
return new ExecutionContext (this);
}
#if NET_4_0
public void Dispose ()
{
#if !MOBILE
@@ -116,7 +157,6 @@ namespace System.Threading {
_sc.Dispose ();
#endif
}
#endif
[MonoTODO]
[ReflectionPermission (SecurityAction.Demand, MemberAccess = true)]
@@ -167,6 +207,8 @@ namespace System.Threading {
set { _suppressFlow = value; }
}
internal bool CopyOnWrite { get; set; }
public static bool IsFlowSuppressed ()
{
return Current.FlowSuppressed;
@@ -180,6 +222,11 @@ namespace System.Threading {
ec.FlowSuppressed = false;
}
internal static void Run(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx)
{
Run (executionContext, callback, state);
}
[SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
public static void Run (ExecutionContext executionContext, ContextCallback callback, object state)
@@ -232,5 +279,16 @@ namespace System.Threading {
return Thread.CurrentThread.ExecutionContext;
}
}
internal static ExecutionContext GetCurrentWritable ()
{
var current = Thread.CurrentThread.ExecutionContext;
if (current.CopyOnWrite) {
current.CopyOnWrite = false;
current.CloneData (current);
}
return current;
}
}
}
}

View File

@@ -29,7 +29,7 @@
namespace System.Threading {
[MonoTODO ("Useless until the runtime supports it")]
public class HostExecutionContext {
public class HostExecutionContext : IDisposable {
private object _state;
@@ -52,5 +52,15 @@ namespace System.Threading {
get { return _state; }
set { _state = value; }
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
public virtual void Dispose (bool disposing)
{
}
}
}

View File

@@ -44,6 +44,10 @@ namespace System.Threading
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static int CompareExchange(ref int location1, int value, int comparand);
[ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int CompareExchange(ref int location1, int value, int comparand, ref bool succeeded);
[ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static object CompareExchange(ref object location1, object value, object comparand);
@@ -118,10 +122,8 @@ namespace System.Threading
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static long Add(ref long location1, long value);
#if NET_4_5
public static void MemoryBarrier () {
Thread.MemoryBarrier ();
}
#endif
}
}

View File

@@ -1,89 +0,0 @@
//
// LazyInitializer.cs
//
// Authors:
// Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
// Marek Safar (marek.safar@gmail.com)
//
// Copyright (c) 2009 Jérémie "Garuma" Laval
// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if NET_4_0
namespace System.Threading
{
public static class LazyInitializer
{
public static T EnsureInitialized<T> (ref T target) where T : class
{
return target ?? EnsureInitialized (ref target, GetDefaultCtorValue<T>);
}
public static T EnsureInitialized<T> (ref T target, Func<T> valueFactory) where T : class
{
if (target == null) {
var value = valueFactory ();
if (value == null)
throw new InvalidOperationException ();
Interlocked.CompareExchange (ref target, value, null);
}
return target;
}
public static T EnsureInitialized<T> (ref T target, ref bool initialized, ref object syncLock)
{
return EnsureInitialized (ref target, ref initialized, ref syncLock, GetDefaultCtorValue<T>);
}
public static T EnsureInitialized<T> (ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory)
{
if (initialized)
return target;
if (syncLock == null)
Interlocked.CompareExchange (ref syncLock, new object (), null);
lock (syncLock) {
if (initialized)
return target;
initialized = true;
Thread.MemoryBarrier ();
target = valueFactory ();
}
return target;
}
static T GetDefaultCtorValue<T> ()
{
try {
return Activator.CreateInstance<T> ();
} catch {
throw new MissingMemberException ("The type being lazily initialized does not have a "
+ "public, parameterless constructor.");
}
}
}
}
#endif

View File

@@ -1,43 +0,0 @@
//
// Lazy.cs
//
// Authors:
// Rodrigo Kumpera (kumpera@gmail.com)
//
// Copyright (C) 2010 Novell
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_0
using System;
namespace System.Threading
{
public enum LazyThreadSafetyMode
{
None,
PublicationOnly,
ExecutionAndPublication
}
}
#endif

View File

@@ -27,7 +27,6 @@
*/
#if NET_4_0
using System;
using System.Runtime.Serialization;
@@ -63,4 +62,3 @@ namespace System.Threading
}
}
#endif

View File

@@ -1,49 +0,0 @@
//
// System.Threading.ManualResetEvent.cs
//
// Author:
// Dick Porter (dick@ximian.com)
// Veronica De Santis (veron78@interfree.it)
//
// (C) Ximian, Inc. http://www.ximian.com
//
//
// Copyright (C) 2004, 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System.Threading
{
[ComVisible (true)]
public sealed class ManualResetEvent : EventWaitHandle
{
// Constructor
public ManualResetEvent (bool initialState)
: base(initialState, EventResetMode.ManualReset)
{
}
}
}

View File

@@ -1,271 +0,0 @@
// ManualResetEventSlim.cs
//
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
// Copyright (c) 2008 Jérémie "Garuma" Laval
// Copyright 2011 Xamarin Inc (http://www.xamarin.com).
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
#if NET_4_0
namespace System.Threading
{
[System.Diagnostics.DebuggerDisplayAttribute ("Set = {IsSet}")]
public class ManualResetEventSlim : IDisposable
{
readonly int spinCount;
ManualResetEvent handle;
internal AtomicBooleanValue disposed;
int used;
int state;
public ManualResetEventSlim ()
: this (false, 10)
{
}
public ManualResetEventSlim (bool initialState)
: this (initialState, 10)
{
}
public ManualResetEventSlim (bool initialState, int spinCount)
{
if (spinCount < 0 || spinCount > 2047)
throw new ArgumentOutOfRangeException ("spinCount");
this.state = initialState ? 1 : 0;
this.spinCount = spinCount;
}
public bool IsSet {
get {
return (state & 1) == 1;
}
}
public int SpinCount {
get {
return spinCount;
}
}
public void Reset ()
{
ThrowIfDisposed ();
var stamp = UpdateStateWithOp (false);
if (handle != null)
CommitChangeToHandle (stamp);
}
public void Set ()
{
var stamp = UpdateStateWithOp (true);
if (handle != null)
CommitChangeToHandle (stamp);
}
long UpdateStateWithOp (bool set)
{
int oldValue, newValue;
do {
oldValue = state;
newValue = (int)(((oldValue >> 1) + 1) << 1) | (set ? 1 : 0);
} while (Interlocked.CompareExchange (ref state, newValue, oldValue) != oldValue);
return newValue;
}
void CommitChangeToHandle (long stamp)
{
Interlocked.Increment (ref used);
var tmpHandle = handle;
if (tmpHandle != null) {
// First in all case we carry the operation we were called for
if ((stamp & 1) == 1)
tmpHandle.Set ();
else
tmpHandle.Reset ();
/* Then what may happen is that the two suboperations (state change and handle change)
* overlapped with others. In our case it doesn't matter if the two suboperations aren't
* executed together at the same time, the only thing we have to make sure of is that both
* state and handle are synchronized on the last visible state change.
*
* For instance if S is state change and H is handle change, for 3 concurrent operations
* we may have the following serialized timeline: S1 S2 H2 S3 H3 H1
* Which is perfectly fine (all S were converted to H at some stage) but in that case
* we have a mismatch between S and H at the end because the last operations done were
* S3/H1. We thus need to repeat H3 to get to the desired final state.
*/
int currentState;
do {
currentState = state;
if (currentState != stamp && (stamp & 1) != (currentState & 1)) {
if ((currentState & 1) == 1)
tmpHandle.Set ();
else
tmpHandle.Reset ();
}
} while (currentState != state);
}
Interlocked.Decrement (ref used);
}
public void Wait ()
{
Wait (CancellationToken.None);
}
public bool Wait (int millisecondsTimeout)
{
return Wait (millisecondsTimeout, CancellationToken.None);
}
public bool Wait (TimeSpan timeout)
{
return Wait (CheckTimeout (timeout), CancellationToken.None);
}
public void Wait (CancellationToken cancellationToken)
{
Wait (Timeout.Infinite, cancellationToken);
}
public bool Wait (int millisecondsTimeout, CancellationToken cancellationToken)
{
if (millisecondsTimeout < -1)
throw new ArgumentOutOfRangeException ("millisecondsTimeout");
ThrowIfDisposed ();
if (!IsSet) {
SpinWait wait = new SpinWait ();
while (!IsSet) {
if (wait.Count < spinCount) {
wait.SpinOnce ();
continue;
}
break;
}
cancellationToken.ThrowIfCancellationRequested ();
if (IsSet)
return true;
WaitHandle handle = WaitHandle;
if (cancellationToken.CanBeCanceled) {
var result = WaitHandle.WaitAny (new[] { handle, cancellationToken.WaitHandle }, millisecondsTimeout, false);
if (result == 1)
throw new OperationCanceledException (cancellationToken);
if (result == WaitHandle.WaitTimeout)
return false;
} else {
if (!handle.WaitOne (millisecondsTimeout, false))
return false;
}
}
return true;
}
public bool Wait (TimeSpan timeout, CancellationToken cancellationToken)
{
return Wait (CheckTimeout (timeout), cancellationToken);
}
public WaitHandle WaitHandle {
get {
ThrowIfDisposed ();
if (handle != null)
return handle;
var isSet = IsSet;
var mre = new ManualResetEvent (IsSet);
if (Interlocked.CompareExchange (ref handle, mre, null) == null) {
//
// Ensure the Set has not ran meantime
//
if (isSet != IsSet) {
if (IsSet) {
mre.Set ();
} else {
mre.Reset ();
}
}
} else {
//
// Release the event when other thread was faster
//
mre.Dispose ();
}
return handle;
}
}
public void Dispose ()
{
Dispose (true);
}
protected virtual void Dispose (bool disposing)
{
if (!disposed.TryRelaxedSet ())
return;
if (handle != null) {
var tmpHandle = Interlocked.Exchange (ref handle, null);
if (used > 0) {
// A tiny wait (just a few cycles normally) before releasing
SpinWait wait = new SpinWait ();
while (used > 0)
wait.SpinOnce ();
}
tmpHandle.Dispose ();
}
}
void ThrowIfDisposed ()
{
if (disposed.Value)
throw new ObjectDisposedException ("ManualResetEventSlim");
}
static int CheckTimeout (TimeSpan timeout)
{
try {
return checked ((int)timeout.TotalMilliseconds);
} catch (System.OverflowException) {
throw new ArgumentOutOfRangeException ("timeout");
}
}
}
}
#endif

View File

@@ -189,7 +189,6 @@ namespace System.Threading
}
}
#if NET_4_0
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static void try_enter_with_atomic_var (object obj, int millisecondsTimeout, ref bool lockTaken);
@@ -224,16 +223,14 @@ namespace System.Threading
try_enter_with_atomic_var (obj, millisecondsTimeout, ref lockTaken);
}
#endif
#if NET_4_5
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static bool Monitor_test_owner (object obj);
public static bool IsEntered (object obj)
public
static bool IsEntered (object obj)
{
return Monitor_test_owner(obj);
}
#endif
}
}

Some files were not shown because too many files have changed in this diff Show More