1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- using System;
- using System.Collections;
- namespace UniRx
- {
- // should be use Interlocked.CompareExchange for Threadsafe?
- // but CompareExchange cause ExecutionEngineException on iOS.
- // AOT...
- // use lock instead
- public sealed class SingleAssignmentDisposable : IDisposable, ICancelable
- {
- readonly object gate = new object();
- IDisposable current;
- bool disposed;
- public bool IsDisposed { get { lock (gate) { return disposed; } } }
- public IDisposable Disposable
- {
- get
- {
- return current;
- }
- set
- {
- var old = default(IDisposable);
- bool alreadyDisposed;
- lock (gate)
- {
- alreadyDisposed = disposed;
- old = current;
- if (!alreadyDisposed)
- {
- if (value == null) return;
- current = value;
- }
- }
- if (alreadyDisposed && value != null)
- {
- value.Dispose();
- return;
- }
- if (old != null) throw new InvalidOperationException("Disposable is already set");
- }
- }
- public void Dispose()
- {
- IDisposable old = null;
- lock (gate)
- {
- if (!disposed)
- {
- disposed = true;
- old = current;
- current = null;
- }
- }
- if (old != null) old.Dispose();
- }
- }
- }
|