efl_mono: Reject the promise when it's disposed.
Summary: As futures are tied to a given promises and are usually handled in a 'attach and forget' scheme, we can't cancel them as it would cancel the whole chain. Reviewers: felipealmeida, vitor.sousa Reviewed By: vitor.sousa Subscribers: cedric, #committers, zmike Tags: #efl Differential Revision: https://phab.enlightenment.org/D6189
This commit is contained in:
parent
b7530726c8
commit
2bbaada66e
|
@ -66,7 +66,7 @@ static internal class PromiseNativeMethods
|
|||
///
|
||||
/// With a Promise you can attach futures to it, which will be used to notify of the value being available.
|
||||
/// </summary>
|
||||
public class Promise
|
||||
public class Promise : IDisposable
|
||||
{
|
||||
internal IntPtr Handle;
|
||||
private GCHandle CleanupHandle;
|
||||
|
@ -116,6 +116,28 @@ public class Promise
|
|||
handle.Free();
|
||||
}
|
||||
|
||||
/// <summary>Dispose this promise, causing its cancellation if it isn't already fulfilled.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>Finalizer to be called from the Garbage Collector.</summary>
|
||||
~Promise()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (Handle != IntPtr.Zero)
|
||||
{
|
||||
eina_promise_reject(Handle, eina.Error.ECANCELED);
|
||||
Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void SanityChecks()
|
||||
{
|
||||
if (this.Handle == IntPtr.Zero)
|
||||
|
|
|
@ -230,6 +230,32 @@ class TestPromises
|
|||
Test.Assert(callbackCalled, "Future callback should have been called.");
|
||||
Test.AssertEquals(received_value, reference_value);
|
||||
}
|
||||
|
||||
public static void test_reject_on_disposal()
|
||||
{
|
||||
bool callbackCalled = false;
|
||||
eina.Error received_error = eina.Error.NO_ERROR;
|
||||
|
||||
efl.ILoop loop = efl.App.GetLoopMain();
|
||||
eina.Promise promise = new eina.Promise();
|
||||
eina.Future future = new eina.Future(promise);
|
||||
|
||||
future = future.Then((eina.Value value) => {
|
||||
callbackCalled = true;
|
||||
value.Get(out received_error);
|
||||
return value;
|
||||
});
|
||||
|
||||
promise.Dispose();
|
||||
|
||||
loop.Iterate();
|
||||
|
||||
Test.Assert(callbackCalled, "Future callback should have been called.");
|
||||
Test.AssertEquals(received_error, eina.Error.ECANCELED);
|
||||
|
||||
Test.AssertRaises<ObjectDisposedException>(() => { promise.Resolve(null); });
|
||||
Test.AssertRaises<ObjectDisposedException>(future.Cancel);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue