diff --git a/Capnp.Net.Runtime/Rpc/IResolvingCapability.cs b/Capnp.Net.Runtime/Rpc/IResolvingCapability.cs
index cc26602..b3dc986 100644
--- a/Capnp.Net.Runtime/Rpc/IResolvingCapability.cs
+++ b/Capnp.Net.Runtime/Rpc/IResolvingCapability.cs
@@ -8,8 +8,15 @@ namespace Capnp.Rpc
public interface IResolvingCapability
{
///
- /// Will eventually give the resolved capability.
+ /// Completes when the capability gets resolved.
///
- Task WhenResolved { get; }
+ Task WhenResolved { get; }
+
+ ///
+ /// Returns the resolved capability
+ ///
+ /// Capability interface or
+ /// the resolved capability, or null if it did not resolve yet
+ T? GetResolvedCapability() where T: class;
}
}
\ No newline at end of file
diff --git a/Capnp.Net.Runtime/Rpc/LazyCapability.cs b/Capnp.Net.Runtime/Rpc/LazyCapability.cs
index 880b837..3e11953 100644
--- a/Capnp.Net.Runtime/Rpc/LazyCapability.cs
+++ b/Capnp.Net.Runtime/Rpc/LazyCapability.cs
@@ -17,10 +17,11 @@ namespace Capnp.Rpc
}
readonly Task? _proxyTask;
+ readonly Task _capTask;
public LazyCapability(Task capabilityTask)
{
- WhenResolved = capabilityTask;
+ _capTask = capabilityTask;
}
public LazyCapability(Task proxyTask)
@@ -29,7 +30,7 @@ namespace Capnp.Rpc
async Task AwaitCap() => (await _proxyTask!).ConsumedCap;
- WhenResolved = AwaitCap();
+ _capTask = AwaitCap();
}
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
@@ -40,7 +41,7 @@ namespace Capnp.Rpc
try
{
- WhenResolved.Result?.Freeze(out boundEndpoint);
+ _capTask.Result?.Freeze(out boundEndpoint);
}
catch (AggregateException exception)
{
@@ -61,7 +62,7 @@ namespace Capnp.Rpc
{
if (WhenResolved.ReplacementTaskIsCompletedSuccessfully())
{
- using var proxy = new Proxy(WhenResolved.Result);
+ using var proxy = GetResolvedCapability()!;
return proxy.Export(endpoint, writer);
}
else
@@ -84,14 +85,33 @@ namespace Capnp.Rpc
}
}
- public Task WhenResolved { get; }
+ public Task WhenResolved => _capTask;
+
+ public T? GetResolvedCapability() where T: class
+ {
+ if (_capTask.IsCompleted)
+ {
+ try
+ {
+ return CapabilityReflection.CreateProxy(_capTask.Result) as T;
+ }
+ catch (AggregateException exception)
+ {
+ throw exception.InnerException!;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
async Task CallImpl(ulong interfaceId, ushort methodId, DynamicSerializerState args, CancellationToken cancellationToken)
{
ConsumedCapability? cap;
try
{
- cap = await WhenResolved;
+ cap = await _capTask;
}
catch
{
diff --git a/Capnp.Net.Runtime/Rpc/LocalAnswerCapability.cs b/Capnp.Net.Runtime/Rpc/LocalAnswerCapability.cs
index 08a5437..e29a1b3 100644
--- a/Capnp.Net.Runtime/Rpc/LocalAnswerCapability.cs
+++ b/Capnp.Net.Runtime/Rpc/LocalAnswerCapability.cs
@@ -21,9 +21,6 @@ namespace Capnp.Rpc
public LocalAnswerCapability(Task proxyTask)
{
_whenResolvedProxy = proxyTask;
-
- async Task AwaitResolved() => (await _whenResolvedProxy).ConsumedCap;
- WhenResolved = AwaitResolved();
}
public LocalAnswerCapability(Task answer, MemberAccessPath access):
@@ -42,7 +39,9 @@ namespace Capnp.Rpc
}
- public Task WhenResolved { get; private set; }
+ public Task WhenResolved => _whenResolvedProxy;
+
+ public T? GetResolvedCapability() where T : class => _whenResolvedProxy.GetResolvedCapability();
internal override Action? Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
{
diff --git a/Capnp.Net.Runtime/Rpc/PromisedCapability.cs b/Capnp.Net.Runtime/Rpc/PromisedCapability.cs
index 0099383..0b5bfbf 100644
--- a/Capnp.Net.Runtime/Rpc/PromisedCapability.cs
+++ b/Capnp.Net.Runtime/Rpc/PromisedCapability.cs
@@ -16,11 +16,12 @@ namespace Capnp.Rpc
{
_remoteId = remoteId;
- async Task AwaitProxy() => new Proxy(await WhenResolved);
+ async Task AwaitProxy() => new Proxy(await _resolvedCap.Task);
_whenResolvedProxy = AwaitProxy();
}
- public override Task WhenResolved => _resolvedCap.Task;
+ public override Task WhenResolved => _resolvedCap.Task;
+ public override T? GetResolvedCapability() where T: class => _whenResolvedProxy.GetResolvedCapability();
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
{
diff --git a/Capnp.Net.Runtime/Rpc/Proxy.cs b/Capnp.Net.Runtime/Rpc/Proxy.cs
index 53ec1af..34f09c1 100644
--- a/Capnp.Net.Runtime/Rpc/Proxy.cs
+++ b/Capnp.Net.Runtime/Rpc/Proxy.cs
@@ -17,7 +17,7 @@ namespace Capnp.Rpc
/// Capability interface
/// instance to share
///
- public static T Share(T obj) where T: class
+ public static T Share(T obj) where T : class
{
if (obj is Proxy proxy)
return proxy.Cast(false);
@@ -32,18 +32,30 @@ namespace Capnp.Rpc
bool _disposedValue = false;
///
- /// Will eventually give the resolved capability, if this is a promised capability.
+ /// Completes when the capability gets resolved.
///
- public Task WhenResolved
+ public Task WhenResolved
{
get
{
- return ConsumedCap is IResolvingCapability resolving ?
- resolving.WhenResolved :
- Task.FromResult(ConsumedCap);
+ return ConsumedCap is IResolvingCapability resolving ?
+ resolving.WhenResolved : Task.CompletedTask;
}
}
+ ///
+ /// Returns the resolved capability
+ ///
+ /// Capability interface or
+ /// the resolved capability, or null if it did not resolve yet
+ public T? GetResolvedCapability() where T : class
+ {
+ if (ConsumedCap is IResolvingCapability resolving)
+ return resolving.GetResolvedCapability();
+ else
+ return CapabilityReflection.CreateProxy(ConsumedCap) as T;
+ }
+
///
/// Underlying low-level capability
///
diff --git a/Capnp.Net.Runtime/Rpc/RemoteAnswerCapability.cs b/Capnp.Net.Runtime/Rpc/RemoteAnswerCapability.cs
index fd47935..734899b 100644
--- a/Capnp.Net.Runtime/Rpc/RemoteAnswerCapability.cs
+++ b/Capnp.Net.Runtime/Rpc/RemoteAnswerCapability.cs
@@ -23,18 +23,6 @@ namespace Capnp.Rpc
_question = question ?? throw new ArgumentNullException(nameof(question));
_access = access ?? throw new ArgumentNullException(nameof(access));
_whenResolvedProxy = proxyTask ?? throw new ArgumentNullException(nameof(proxyTask));
-
- async Task AwaitWhenResolved()
- {
- var proxy = await _whenResolvedProxy;
-
- if (_question.IsTailCall)
- throw new InvalidOperationException("Question is a tail call, so won't resolve back.");
-
- return proxy.ConsumedCap;
- }
-
- WhenResolved = AwaitWhenResolved();
}
static async Task TransferOwnershipToDummyProxy(PendingQuestion question, MemberAccessPath access)
@@ -81,7 +69,7 @@ namespace Capnp.Rpc
{
try
{
- return WhenResolved.Result;
+ return _whenResolvedProxy.Result.ConsumedCap;
}
catch (AggregateException exception)
{
@@ -96,7 +84,9 @@ namespace Capnp.Rpc
}
}
- public override Task WhenResolved { get; }
+ public override Task WhenResolved => _whenResolvedProxy;
+
+ public override T? GetResolvedCapability() where T: class => _whenResolvedProxy.GetResolvedCapability();
protected override void GetMessageTarget(MessageTarget.WRITER wr)
{
diff --git a/Capnp.Net.Runtime/Rpc/RemoteResolvingCapability.cs b/Capnp.Net.Runtime/Rpc/RemoteResolvingCapability.cs
index b6a9cf8..6f3ba0b 100644
--- a/Capnp.Net.Runtime/Rpc/RemoteResolvingCapability.cs
+++ b/Capnp.Net.Runtime/Rpc/RemoteResolvingCapability.cs
@@ -16,7 +16,8 @@ namespace Capnp.Rpc
ILogger Logger { get; } = Logging.CreateLogger();
#endif
- public abstract Task WhenResolved { get; }
+ public abstract Task WhenResolved { get; }
+ public abstract T? GetResolvedCapability() where T : class;
protected RemoteResolvingCapability(IRpcEndpoint ep) : base(ep)
{
diff --git a/Capnp.Net.Runtime/Rpc/ResolvingCapabilityExtensions.cs b/Capnp.Net.Runtime/Rpc/ResolvingCapabilityExtensions.cs
index 23b3fab..7fae258 100644
--- a/Capnp.Net.Runtime/Rpc/ResolvingCapabilityExtensions.cs
+++ b/Capnp.Net.Runtime/Rpc/ResolvingCapabilityExtensions.cs
@@ -9,7 +9,9 @@ namespace Capnp.Rpc
{
while (cap is IResolvingCapability resolving)
{
- cap = await resolving.WhenResolved;
+ await resolving.WhenResolved;
+ using var proxy = resolving.GetResolvedCapability()!;
+ cap = proxy.ConsumedCap;
}
return cap;
@@ -30,7 +32,9 @@ namespace Capnp.Rpc
try
{
- var resolvedCap = await Unwrap(await cap.WhenResolved);
+ await cap.WhenResolved;
+ using var proxy = cap.GetResolvedCapability()!;
+ var resolvedCap = await Unwrap(proxy.ConsumedCap);
endpoint.Resolve(preliminaryId, vine, () => resolvedCap!);
}
catch (System.Exception exception)
@@ -68,5 +72,24 @@ namespace Capnp.Rpc
default: return BareProxy.FromImpl(obj);
}
}
+
+ public static T? GetResolvedCapability(this Task proxyTask) where T: class
+ {
+ if (proxyTask.IsCompleted)
+ {
+ try
+ {
+ return proxyTask.Result.Cast(false);
+ }
+ catch (AggregateException exception)
+ {
+ throw exception.InnerException!;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
}
}
\ No newline at end of file