You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.0 KiB
127 lines
3.0 KiB
#if FAT |
|
|
|
using System; |
|
using System.Threading; |
|
|
|
using LinqInternal.Core; |
|
|
|
namespace LinqInternal.Threading |
|
{ |
|
[System.Diagnostics.DebuggerNonUserCode] |
|
internal sealed class DisposableAkin : |
|
#if !NETCOREAPP1_1 |
|
System.Runtime.ConstrainedExecution.CriticalFinalizerObject, |
|
#endif |
|
IDisposable |
|
{ |
|
private Action _release; |
|
private Thread _thread; |
|
|
|
private DisposableAkin(Action release, Thread thread) |
|
{ |
|
if (release == null) |
|
{ |
|
throw new ArgumentNullException("release"); |
|
} |
|
if (thread == null) |
|
{ |
|
throw new ArgumentNullException("thread"); |
|
} |
|
_release = release; |
|
_thread = thread; |
|
} |
|
|
|
~DisposableAkin() |
|
{ |
|
try |
|
{ |
|
// Empty |
|
} |
|
finally |
|
{ |
|
try |
|
{ |
|
Dispose(false); |
|
} |
|
catch (Exception exception) |
|
{ |
|
// Catch'em all - fields may be partially collected. |
|
GC.KeepAlive(exception); |
|
} |
|
} |
|
} |
|
|
|
public bool IsDisposed |
|
{ |
|
get { return _thread == null; } |
|
} |
|
|
|
public static DisposableAkin Create(Action release) |
|
{ |
|
return new DisposableAkin(release, Thread.CurrentThread); |
|
} |
|
|
|
public static DisposableAkin Create() |
|
{ |
|
return new DisposableAkin(ActionHelper.GetNoopAction(), Thread.CurrentThread); |
|
} |
|
|
|
public bool Dispose(Func<bool> condition) |
|
{ |
|
if (condition == null) |
|
{ |
|
throw new ArgumentNullException("condition"); |
|
} |
|
if (ReferenceEquals(Interlocked.CompareExchange(ref _thread, null, Thread.CurrentThread), Thread.CurrentThread)) |
|
{ |
|
if (condition.Invoke()) |
|
{ |
|
try |
|
{ |
|
_release.Invoke(); |
|
return true; |
|
} |
|
finally |
|
{ |
|
_release = null; |
|
} |
|
} |
|
return false; |
|
} |
|
return false; |
|
} |
|
|
|
public void Dispose() |
|
{ |
|
try |
|
{ |
|
Dispose(true); |
|
} |
|
finally |
|
{ |
|
GC.SuppressFinalize(this); |
|
} |
|
} |
|
|
|
private void Dispose(bool disposeManagedResources) |
|
{ |
|
if |
|
( |
|
!disposeManagedResources |
|
|| ReferenceEquals(Interlocked.CompareExchange(ref _thread, null, Thread.CurrentThread), Thread.CurrentThread) |
|
) |
|
{ |
|
try |
|
{ |
|
_release.Invoke(); |
|
} |
|
finally |
|
{ |
|
_release = null; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
#endif |