Beispiel #1
0
        public static Action?ExportAsSenderPromise <T>(this T cap, IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
            where T : ConsumedCapability, IResolvingCapability
        {
            var  vine          = cap.AsSkeleton();
            uint preliminaryId = endpoint.AllocateExport(vine, out bool first);

            writer.which         = CapDescriptor.WHICH.SenderPromise;
            writer.SenderPromise = preliminaryId;

            if (first)
            {
                return(async() => {
                    try
                    {
                        await cap.WhenResolved;
                        using var proxy = cap.GetResolvedCapability <BareProxy>() !;
                        var resolvedCap = await Unwrap(proxy.ConsumedCap);

                        endpoint.Resolve(preliminaryId, vine, () => resolvedCap !);
                    }
                    catch (System.Exception exception)
                    {
                        endpoint.Resolve(preliminaryId, vine, () => throw exception);
                    }
                });
            }

            return(null);
        }
Beispiel #2
0
        public static void ExportAsSenderPromise <T>(this T cap, IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
            where T : ConsumedCapability, IResolvingCapability
        {
            var  vine          = Vine.Create(cap);
            uint preliminaryId = endpoint.AllocateExport(vine, out bool first);

            writer.which         = CapDescriptor.WHICH.SenderPromise;
            writer.SenderPromise = preliminaryId;

            if (first)
            {
                endpoint.RequestPostAction(async() => {
                    try
                    {
                        var resolvedCap = await cap.WhenResolved;

                        endpoint.Resolve(preliminaryId, vine, () => resolvedCap.ConsumedCap !);
                    }
                    catch (System.Exception exception)
                    {
                        endpoint.Resolve(preliminaryId, vine, () => throw exception);
                    }
                });
            }
        }
Beispiel #3
0
        public PromisedCapability(IRpcEndpoint ep, uint remoteId) : base(ep)
        {
            _remoteId = remoteId;

            async Task <Proxy> AwaitProxy() => new Proxy(await _resolvedCap.Task);

            _whenResolvedProxy = AwaitProxy().EnforceAwaitOrder();
        }
Beispiel #4
0
        internal void Freeze(out IRpcEndpoint boundEndpoint)
        {
            if (_disposedValue)
            {
                throw new ObjectDisposedException(nameof(Proxy));
            }

            boundEndpoint = null;
            ConsumedCap?.Freeze(out boundEndpoint);
        }
Beispiel #5
0
 internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
 {
     if (WhenResolved.IsCompletedSuccessfully)
     {
         WhenResolved.Result.Export(endpoint, writer);
     }
     else
     {
         this.ExportAsSenderPromise(endpoint, writer);
     }
 }
 internal override Action?Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
 {
     if (WhenResolved.IsCompleted && WhenResolved.WrappedTask.ReplacementTaskIsCompletedSuccessfully())
     {
         using var proxy = GetResolvedCapability <BareProxy>() !;
         return(proxy.Export(endpoint, writer));
     }
     else
     {
         return(this.ExportAsSenderPromise(endpoint, writer));
     }
 }
Beispiel #7
0
 internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER capDesc)
 {
     if (endpoint == _ep)
     {
         capDesc.which          = CapDescriptor.WHICH.ReceiverHosted;
         capDesc.ReceiverHosted = _remoteId;
     }
     else
     {
         capDesc.which        = CapDescriptor.WHICH.SenderHosted;
         capDesc.SenderHosted = endpoint.AllocateExport(Vine.Create(this), out var _);
     }
 }
Beispiel #8
0
 internal override Action?Export(IRpcEndpoint endpoint, CapDescriptor.WRITER capDesc)
 {
     if (endpoint == _ep)
     {
         capDesc.which          = CapDescriptor.WHICH.ReceiverHosted;
         capDesc.ReceiverHosted = _remoteId;
     }
     else
     {
         capDesc.which        = CapDescriptor.WHICH.SenderHosted;
         capDesc.SenderHosted = endpoint.AllocateExport(AsSkeleton(), out var _);
     }
     return(null);
 }
        internal PendingQuestion(IRpcEndpoint ep, uint id, ConsumedCapability target, SerializerState?inParams)
        {
            RpcEndpoint   = ep ?? throw new ArgumentNullException(nameof(ep));
            _questionId   = id;
            _target       = target;
            _inParams     = inParams;
            _whenReturned = _tcs.Task.EnforceAwaitOrder();

            StateFlags = inParams == null ? State.Sent : State.None;

            if (target != null)
            {
                target.AddRef();
            }
        }
Beispiel #10
0
        internal void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
        {
            if (_disposedValue)
            {
                throw new ObjectDisposedException(nameof(Proxy));
            }

            if (ConsumedCap == null)
            {
                writer.which = CapDescriptor.WHICH.None;
            }
            else
            {
                ConsumedCap.Export(endpoint, writer);
            }
        }
Beispiel #11
0
        internal override Action?Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
        {
            lock (_reentrancyBlocker)
            {
                if (_resolvedCap.Task.ReplacementTaskIsCompletedSuccessfully())
                {
                    using var proxy = new Proxy(_resolvedCap.Task.Result);
                    proxy.Export(endpoint, writer);
                }
                else
                {
                    if (_ep == endpoint)
                    {
                        writer.which          = CapDescriptor.WHICH.ReceiverHosted;
                        writer.ReceiverHosted = _remoteId;

                        Debug.Assert(!_released);
                        ++_pendingCallsOnPromise;

                        return(() =>
                        {
                            bool release = false;

                            lock (_reentrancyBlocker)
                            {
                                if (--_pendingCallsOnPromise == 0 && _resolvedCap.Task.IsCompleted)
                                {
                                    _released = true;
                                    release = true;
                                }
                            }

                            if (release)
                            {
                                _ep.ReleaseImport(_remoteId);
                            }
                        });
                    }
                    else
                    {
                        this.ExportAsSenderPromise(endpoint, writer);
                    }
                }
            }

            return(null);
        }
        internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
        {
            lock (_question.ReentrancyBlocker)
            {
                if (_question.StateFlags.HasFlag(PendingQuestion.State.Disposed))
                {
                    throw new ObjectDisposedException(nameof(PendingQuestion));
                }

                if (_question.StateFlags.HasFlag(PendingQuestion.State.Returned))
                {
                    ResolvedCap.Export(endpoint, writer);
                }
                else
                {
                    if (_question.StateFlags.HasFlag(PendingQuestion.State.FinishRequested))
                    {
                        throw new InvalidOperationException("Finish request was already sent");
                    }

                    if (endpoint == _ep)
                    {
                        writer.which = CapDescriptor.WHICH.ReceiverAnswer;
                        _access.Serialize(writer.ReceiverAnswer);
                        writer.ReceiverAnswer.QuestionId = _question.QuestionId;
                    }
                    else if (_question.IsTailCall)
                    {
                        // FIXME: Resource management! We should prevent finishing this
                        // cap as long as it is exported. Unfortunately, we cannot determine
                        // when it gets removed from the export table.

                        var  vine = Vine.Create(this);
                        uint id   = endpoint.AllocateExport(vine, out bool first);

                        writer.which        = CapDescriptor.WHICH.SenderHosted;
                        writer.SenderHosted = id;
                    }
                    else
                    {
                        this.ExportAsSenderPromise(endpoint, writer);
                    }
                }
            }
        }
Beispiel #13
0
 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;
     }
 }
Beispiel #14
0
        internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
        {
            lock (_reentrancyBlocker)
            {
                if (_resolvedCap.Task.IsCompletedSuccessfully)
                {
                    _resolvedCap.Task.Result.Export(endpoint, writer);
                }
                else
                {
                    if (_ep == endpoint)
                    {
                        writer.which          = CapDescriptor.WHICH.ReceiverHosted;
                        writer.ReceiverHosted = _remoteId;

                        Debug.Assert(!_released);
                        ++_pendingCallsOnPromise;

                        _ep.RequestPostAction(() =>
                        {
                            bool release = false;

                            lock (_reentrancyBlocker)
                            {
                                if (--_pendingCallsOnPromise == 0 && _resolvedCap.Task.IsCompleted)
                                {
                                    _released = true;
                                    release   = true;
                                }
                            }

                            if (release)
                            {
                                _ep.ReleaseImport(_remoteId);
                            }
                        });
                    }
                    else
                    {
                        this.ExportAsSenderPromise(endpoint, writer);
                    }
                }
            }
        }
Beispiel #15
0
        internal override Action?Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
        {
            lock (_question.ReentrancyBlocker)
            {
                if (_question.StateFlags.HasFlag(PendingQuestion.State.CanceledByDispose))
                {
                    throw new ObjectDisposedException(nameof(PendingQuestion));
                }

                if (_question.StateFlags.HasFlag(PendingQuestion.State.Returned) && !_question.IsTailCall)
                {
                    ResolvedCap !.Export(endpoint, writer);
                }
                else
                {
                    if (_question.StateFlags.HasFlag(PendingQuestion.State.FinishRequested))
                    {
                        throw new InvalidOperationException("Finish request was already sent");
                    }

                    if (endpoint == _ep)
                    {
                        writer.which = CapDescriptor.WHICH.ReceiverAnswer;
                        _access.Serialize(writer.ReceiverAnswer !);
                        writer.ReceiverAnswer !.QuestionId = _question.QuestionId;
                    }
                    else if (_question.IsTailCall)
                    {
                        uint id = endpoint.AllocateExport(AsSkeleton(), out bool first);

                        writer.which        = CapDescriptor.WHICH.SenderHosted;
                        writer.SenderHosted = id;
                    }
                    else
                    {
                        return(this.ExportAsSenderPromise(endpoint, writer));
                    }
                }
            }

            return(null);
        }
Beispiel #16
0
        internal override Action?Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
        {
            if (_whenResolvedProxy.IsCompleted)
            {
                try
                {
                    _whenResolvedProxy.Result.Export(endpoint, writer);
                }
                catch (AggregateException exception)
                {
                    throw exception.InnerException !;
                }

                return(null);
            }
            else
            {
                return(this.ExportAsSenderPromise(endpoint, writer));
            }
        }
        internal PendingQuestion(IRpcEndpoint ep, uint id, ConsumedCapability target, SerializerState inParams)
        {
            RpcEndpoint = ep ?? throw new ArgumentNullException(nameof(ep));
            _questionId = id;
            _target     = target;
            _inParams   = inParams;
            StateFlags  = inParams == null ? State.Sent : State.None;

            if (inParams != null)
            {
                foreach (var cap in inParams.Caps)
                {
                    cap?.AddRef();
                }
            }

            if (target != null)
            {
                target.AddRef();
            }
        }
        internal override void Freeze(out IRpcEndpoint boundEndpoint)
        {
            lock (_question.ReentrancyBlocker)
            {
                if (_question.StateFlags.HasFlag(PendingQuestion.State.Returned) &&
                    _pendingCallsOnPromise == 0)
                {
                    if (ResolvedCap == null)
                    {
                        throw new RpcException("Answer did not resolve to expected capability");
                    }

                    ResolvedCap.Freeze(out boundEndpoint);
                }
                else
                {
                    ++_pendingCallsOnPromise;
                    _question.DisallowFinish();
                    boundEndpoint = _ep;
                }
            }
        }
        internal override void Freeze(out IRpcEndpoint boundEndpoint)
        {
            lock (_reentrancyBlocker)
            {
                if (_resolvedCap.Task.IsCompleted && _pendingCallsOnPromise == 0)
                {
                    try
                    {
                        _resolvedCap.Task.Result.Freeze(out boundEndpoint);
                    }
                    catch (AggregateException exception)
                    {
                        throw exception.InnerException;
                    }
                }
                else
                {
                    Debug.Assert(!_released);
                    ++_pendingCallsOnPromise;

                    boundEndpoint = _ep;
                }
            }
        }
Beispiel #20
0
        internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
        {
            if (_answer.IsCompleted)
            {
                DeserializerState result;
                try
                {
                    result = _answer.Result;
                }
                catch (AggregateException exception)
                {
                    throw exception.InnerException;
                }

                using (var proxy = new Proxy(_access.Eval(result)))
                {
                    proxy.Export(endpoint, writer);
                }
            }
            else
            {
                this.ExportAsSenderPromise(endpoint, writer);
            }
        }
 internal abstract void Freeze(out IRpcEndpoint boundEndpoint);
 internal abstract void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer);
Beispiel #23
0
 internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
 {
     writer.which        = CapDescriptor.WHICH.SenderHosted;
     writer.SenderHosted = endpoint.AllocateExport(MyVine, out bool _);
 }
 internal override void Freeze(out IRpcEndpoint boundEndpoint)
 {
     boundEndpoint = null;
 }
 internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER capDesc)
 {
     capDesc.which        = CapDescriptor.WHICH.SenderHosted;
     capDesc.SenderHosted = endpoint.AllocateExport(ProvidedCap, out bool _);
 }
 protected RemoteCapability(IRpcEndpoint ep)
 {
     _ep = ep;
 }
Beispiel #27
0
 protected RemoteResolvingCapability(IRpcEndpoint ep) : base(ep)
 {
 }
Beispiel #28
0
 public ImportedCapability(IRpcEndpoint ep, uint remoteId) : base(ep)
 {
     _remoteId = remoteId;
 }
 internal override Action?Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
 {
     writer.which = CapDescriptor.WHICH.None;
     return(null);
 }
 public PromisedCapability(IRpcEndpoint ep, uint remoteId) : base(ep)
 {
     _remoteId = remoteId;
 }