public async Task WriteAsync(CapnpNet.Message msg) { await _semaphore.WaitAsync(); try { await msg.SerializeAsync(_writeStream); } finally { _semaphore.Release(); } msg.Dispose(); }
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) { } }); }