Files
Capnp.Net.Runtime
Rpc
AnswerOrCounterquestion.cs
BareProxy.cs
CapabilityReflection.cs
ConsumedCapability.cs
IEndpoint.cs
IMonoSkeleton.cs
IPromisedAnswer.cs
IProvidedCapability.cs
IResolvingCapability.cs
IRpcEndpoint.cs
Impatient.cs
ImportedCapability.cs
InvalidCapabilityInterfaceException.cs
LazyCapability.cs
LocalAnswer.cs
LocalAnswerCapability.cs
LocalCapability.cs
MemberAccessPath.cs
PendingAnswer.cs
PendingQuestion.cs
PolySkeleton.cs
PromisedCapability.cs
Proxy.cs
ProxyAttribute.cs
RefCountingCapability.cs
RemoteAnswerCapability.cs
RemoteCapability.cs
RemoteResolvingCapability.cs
ResolvingCapabilityExtensions.cs
RpcEngine.cs
RpcException.cs
RpcUnimplementedException.cs
Skeleton.cs
SkeletonAttribute.cs
TcpRpcClient.cs
TcpRpcServer.cs
Vine.cs
rpc.cs
AnyPointer.cs
Capnp.Net.Runtime.Std20.xml
Capnp.Net.Runtime.csproj
CapnpSerializable.cs
DeserializationException.cs
DeserializerState.cs
DynamicSerializerState.cs
EmptyList.cs
EmptyListDeserializer.cs
FramePump.cs
Framing.cs
ICapnpSerializable.cs
ISegmentAllocator.cs
IStructDeserializer.cs
IStructSerializer.cs
ListDeserializer.cs
ListKind.cs
ListOfBitsDeserializer.cs
ListOfBitsSerializer.cs
ListOfCapsDeserializer.cs
ListOfCapsSerializer.cs
ListOfEmptyDeserializer.cs
ListOfEmptySerializer.cs
ListOfPointersDeserializer.cs
ListOfPointersSerializer.cs
ListOfPrimitivesDeserializer.cs
ListOfPrimitivesSerializer.cs
ListOfStructsDeserializer.cs
ListOfStructsSerializer.cs
ListOfTextSerializer.cs
Logging.cs
MessageBuilder.cs
ObjectKind.cs
PrimitiveCoder.cs
ReadOnlyListExtensions.cs
Reserializing.cs
SecurityOptions.cs
SegmentAllocator.cs
SegmentSlice.cs
SerializerExtensions.cs
SerializerState.cs
UtilityExtensions.cs
WireFrame.cs
WirePointer.cs
Capnp.Net.Runtime.Core21
Capnp.Net.Runtime.Tests
Capnp.Net.Runtime.Tests.Core21
CapnpCompatTest
Capnpc.Csharp.MsBuild.Generation
Licenses
capnpc-csharp
capnpc-csharp.tests
chocolatey
install-test
scripts
.gitattributes
.gitignore
Capnp.Net.sln
CapnpCompatTest.sln
LICENSE
README.md
appveyor.yml
test.capnp.bin
libs.capnproto-dotnetcore_R…/Capnp.Net.Runtime/Rpc/LazyCapability.cs
2019-06-22 18:43:30 -04:00

111 lines
3.2 KiB
C#

using System;
using System.Threading;
using System.Threading.Tasks;
namespace Capnp.Rpc
{
class LazyCapability : RefCountingCapability, IResolvingCapability
{
public static LazyCapability CreateBrokenCap(string message)
{
var cap = new LazyCapability(Task.FromException<Proxy>(new RpcException(message)));
cap.AddRef(); // Instance shall be persistent
return cap;
}
public static LazyCapability CreateCanceledCap(CancellationToken token)
{
var cap = new LazyCapability(Task.FromCanceled<Proxy>(token));
cap.AddRef(); // Instance shall be persistent
return cap;
}
public static LazyCapability Null { get; } = CreateBrokenCap("Null capability");
public LazyCapability(Task<Proxy> capabilityTask)
{
WhenResolved = capabilityTask;
}
internal override void Freeze(out IRpcEndpoint boundEndpoint)
{
if (WhenResolved.IsCompleted)
{
try
{
WhenResolved.Result.Freeze(out boundEndpoint);
}
catch (AggregateException exception)
{
throw exception.InnerException;
}
}
else
{
boundEndpoint = null;
}
}
internal override void Unfreeze()
{
}
internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
{
if (WhenResolved.ReplacementTaskIsCompletedSuccessfully())
{
WhenResolved.Result.Export(endpoint, writer);
}
else
{
this.ExportAsSenderPromise(endpoint, writer);
}
}
async void DisposeProxyWhenResolved()
{
try
{
var cap = await WhenResolved;
if (cap != null) cap.Dispose();
}
catch
{
}
}
protected override void ReleaseRemotely()
{
DisposeProxyWhenResolved();
}
public Task<Proxy> WhenResolved { get; }
async Task<DeserializerState> CallImpl(ulong interfaceId, ushort methodId,
DynamicSerializerState args, bool pipeline,
CancellationToken cancellationToken)
{
var cap = await WhenResolved;
cancellationToken.ThrowIfCancellationRequested();
if (cap == null)
throw new RpcException("Broken capability");
var call = cap.Call(interfaceId, methodId, args, pipeline);
var whenReturned = call.WhenReturned;
using (var registration = cancellationToken.Register(call.Dispose))
{
return await whenReturned;
}
}
internal override IPromisedAnswer DoCall(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool pipeline)
{
var cts = new CancellationTokenSource();
return new LocalAnswer(cts, CallImpl(interfaceId, methodId, args, pipeline, cts.Token));
}
}
}