Beispiel #1
0
        public async Task WriteAsync(CapnpNet.Message msg)
        {
            await _semaphore.WaitAsync();

            try
            {
                await msg.SerializeAsync(_writeStream);
            }
            finally
            {
                _semaphore.Release();
            }

            msg.Dispose();
        }
Beispiel #2
0
        internal void Process(CapnpNet.Message rpcMessage)
        {
            try
            {
                var message = rpcMessage.GetRoot <Message>();
                if (message.Is(out Message unimplemented))
                {
                    // TODO: release resources
                    throw new NotImplementedException();
                }
                else if (message.Is(out Exception abort))
                {
                    throw new InvalidOperationException($"Connection aborted by remote: {abort.type.ToString()}: {abort.reason.ToString()}");
                }
                else if (message.Is(out Bootstrap bootstrap))
                {
                    var reply = new CapnpNet.Message().Init(_segFactory, true);
                    //await reply.PreAllocateAsync(senderMsg.CalculateSize() + 3);
                    reply.SetRoot(new Return(reply)
                    {
                        answerId = bootstrap.questionId,
                        which    = Return.Union.results,
                        results  = new Payload
                        {
                            content = new OtherPointer
                            {
                                Type             = PointerType.Other,
                                OtherPointerType = OtherPointerType.Capability,
                                CapabilityId     = 0
                            },
                            capTable = new FlatArray <CapDescriptor>(reply, 1, out AllocationContext allocContext)
                            {
                                new CapDescriptor(ref allocContext)
                                {
                                    which        = CapDescriptor.Union.senderHosted,
                                    senderHosted = this.ExportCap(_bootstrapCap)
                                }
                            }
                        }
                    });
                    rpcMessage.Dispose();
                    rpcMessage = null;
                    this.Consume((msgStream: _msgStream, reply: reply), async state =>
                    {
                        await state.msgStream.WriteAsync(state.reply);
                        state.reply.Dispose();
                    });
                }
                else if (message.Is(out Call call))
                {
                    bool       valid;
                    ref Answer ans = ref _answers.TryGet(call.questionId, out valid);
                    if (!valid)
                    {
                        // TODO: return exception message
                    }

                    if (call.target.which == MessageTarget.Union.importedCap)
                    {
                        ref Export export = ref _exports.TryGet(call.target.importedCap, out valid);
                        if (!valid)
                        {
                            // TODO: return exception message
                        }

                        // TODO: read cap descriptors, look up corresponding imports, await any still pending

                        if ([email protected](out var @struct) == false)
                        {
                            // TODO: return exception
                        }

                        switch (call.sendResultsTo.which)
                        {
                        case Call.sendResultsToGroup.Union.caller:
                            // set up return message
                            break;

                        case Call.sendResultsToGroup.Union.yourself:
                            // set aside memory to hold result
                            break;

                        case Call.sendResultsToGroup.Union.thirdParty:
                        default:
                            throw new NotImplementedException();
                        }

                        //ans.task = export.capability.DispatchCall(
                        //  call.interfaceId,
                        //  call.methodId,
                        //  new CallContext(call, this),
                        //  CancellationToken.None);

                        var callTask = ans.task;
                        this.Consume(async() =>
                        {
                            await callTask;
                            if (call.sendResultsTo.which == Call.sendResultsToGroup.Union.caller)
                            {
                            }
                        });
                    }