annotate win64-msvc/include/capnp/rpc.h @ 134:41e769c91eca

Add Capnp and KJ builds for OSX
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 25 Oct 2016 14:48:23 +0100
parents 42a73082be24
children 0f2d93caa50c
rev   line source
cannam@132 1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
cannam@132 2 // Licensed under the MIT License:
cannam@132 3 //
cannam@132 4 // Permission is hereby granted, free of charge, to any person obtaining a copy
cannam@132 5 // of this software and associated documentation files (the "Software"), to deal
cannam@132 6 // in the Software without restriction, including without limitation the rights
cannam@132 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
cannam@132 8 // copies of the Software, and to permit persons to whom the Software is
cannam@132 9 // furnished to do so, subject to the following conditions:
cannam@132 10 //
cannam@132 11 // The above copyright notice and this permission notice shall be included in
cannam@132 12 // all copies or substantial portions of the Software.
cannam@132 13 //
cannam@132 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
cannam@132 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
cannam@132 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
cannam@132 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
cannam@132 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
cannam@132 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
cannam@132 20 // THE SOFTWARE.
cannam@132 21
cannam@132 22 #ifndef CAPNP_RPC_H_
cannam@132 23 #define CAPNP_RPC_H_
cannam@132 24
cannam@132 25 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS)
cannam@132 26 #pragma GCC system_header
cannam@132 27 #endif
cannam@132 28
cannam@132 29 #include "capability.h"
cannam@132 30 #include "rpc-prelude.h"
cannam@132 31
cannam@132 32 namespace capnp {
cannam@132 33
cannam@132 34 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 35 typename ThirdPartyCapId, typename JoinResult>
cannam@132 36 class VatNetwork;
cannam@132 37 template <typename SturdyRefObjectId>
cannam@132 38 class SturdyRefRestorer;
cannam@132 39
cannam@132 40 template <typename VatId>
cannam@132 41 class BootstrapFactory: public _::BootstrapFactoryBase {
cannam@132 42 // Interface that constructs per-client bootstrap interfaces. Use this if you want each client
cannam@132 43 // who connects to see a different bootstrap interface based on their (authenticated) VatId.
cannam@132 44 // This allows an application to bootstrap off of the authentication performed at the VatNetwork
cannam@132 45 // level. (Typically VatId is some sort of public key.)
cannam@132 46 //
cannam@132 47 // This is only useful for multi-party networks. For TwoPartyVatNetwork, there's no reason to
cannam@132 48 // use a BootstrapFactory; just specify a single bootstrap capability in this case.
cannam@132 49
cannam@132 50 public:
cannam@132 51 virtual Capability::Client createFor(typename VatId::Reader clientId) = 0;
cannam@132 52 // Create a bootstrap capability appropriate for exposing to the given client. VatNetwork will
cannam@132 53 // have authenticated the client VatId before this is called.
cannam@132 54
cannam@132 55 private:
cannam@132 56 Capability::Client baseCreateFor(AnyStruct::Reader clientId) override;
cannam@132 57 };
cannam@132 58
cannam@132 59 template <typename VatId>
cannam@132 60 class RpcSystem: public _::RpcSystemBase {
cannam@132 61 // Represents the RPC system, which is the portal to objects available on the network.
cannam@132 62 //
cannam@132 63 // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork`
cannam@132 64 // determines how to form connections between vats -- specifically, two-way, private, reliable,
cannam@132 65 // sequenced datagram connections. The RPC implementation determines how to use such connections
cannam@132 66 // to manage object references and make method calls.
cannam@132 67 //
cannam@132 68 // See `makeRpcServer()` and `makeRpcClient()` below for convenient syntax for setting up an
cannam@132 69 // `RpcSystem` given a `VatNetwork`.
cannam@132 70 //
cannam@132 71 // See `ez-rpc.h` for an even simpler interface for setting up RPC in a typical two-party
cannam@132 72 // client/server scenario.
cannam@132 73
cannam@132 74 public:
cannam@132 75 template <typename ProvisionId, typename RecipientId,
cannam@132 76 typename ThirdPartyCapId, typename JoinResult>
cannam@132 77 RpcSystem(
cannam@132 78 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 79 kj::Maybe<Capability::Client> bootstrapInterface,
cannam@132 80 kj::Maybe<RealmGateway<>::Client> gateway = nullptr);
cannam@132 81
cannam@132 82 template <typename ProvisionId, typename RecipientId,
cannam@132 83 typename ThirdPartyCapId, typename JoinResult>
cannam@132 84 RpcSystem(
cannam@132 85 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 86 BootstrapFactory<VatId>& bootstrapFactory,
cannam@132 87 kj::Maybe<RealmGateway<>::Client> gateway = nullptr);
cannam@132 88
cannam@132 89 template <typename ProvisionId, typename RecipientId,
cannam@132 90 typename ThirdPartyCapId, typename JoinResult,
cannam@132 91 typename LocalSturdyRefObjectId>
cannam@132 92 RpcSystem(
cannam@132 93 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 94 SturdyRefRestorer<LocalSturdyRefObjectId>& restorer);
cannam@132 95
cannam@132 96 RpcSystem(RpcSystem&& other) = default;
cannam@132 97
cannam@132 98 Capability::Client bootstrap(typename VatId::Reader vatId);
cannam@132 99 // Connect to the given vat and return its bootstrap interface.
cannam@132 100
cannam@132 101 Capability::Client restore(typename VatId::Reader hostId, AnyPointer::Reader objectId)
cannam@132 102 KJ_DEPRECATED("Please transition to using a bootstrap interface instead.");
cannam@132 103 // ** DEPRECATED **
cannam@132 104 //
cannam@132 105 // Restores the given SturdyRef from the network and return the capability representing it.
cannam@132 106 //
cannam@132 107 // `hostId` identifies the host from which to request the ref, in the format specified by the
cannam@132 108 // `VatNetwork` in use. `objectId` is the object ID in whatever format is expected by said host.
cannam@132 109 //
cannam@132 110 // This method will be removed in a future version of Cap'n Proto. Instead, please transition
cannam@132 111 // to using bootstrap(), which is equivalent to calling restore() with a null `objectId`.
cannam@132 112 // You may emulate the old concept of object IDs by exporting a bootstrap interface which has
cannam@132 113 // methods that can be used to obtain other capabilities by ID.
cannam@132 114
cannam@132 115 void setFlowLimit(size_t words);
cannam@132 116 // Sets the incoming call flow limit. If more than `words` worth of call messages have not yet
cannam@132 117 // received responses, the RpcSystem will not read further messages from the stream. This can be
cannam@132 118 // used as a crude way to prevent a resource exhaustion attack (or bug) in which a peer makes an
cannam@132 119 // excessive number of simultaneous calls that consume the receiver's RAM.
cannam@132 120 //
cannam@132 121 // There are some caveats. When over the flow limit, all messages are blocked, including returns.
cannam@132 122 // If the outstanding calls are themselves waiting on calls going in the opposite direction, the
cannam@132 123 // flow limit may prevent those calls from completing, leading to deadlock. However, a
cannam@132 124 // sufficiently high limit should make this unlikely.
cannam@132 125 //
cannam@132 126 // Note that a call's parameter size counts against the flow limit until the call returns, even
cannam@132 127 // if the recipient calls releaseParams() to free the parameter memory early. This is because
cannam@132 128 // releaseParams() may simply indicate that the parameters have been forwarded to another
cannam@132 129 // machine, but are still in-memory there. For illustration, say that Alice made a call to Bob
cannam@132 130 // who forwarded the call to Carol. Bob has imposed a flow limit on Alice. Alice's calls are
cannam@132 131 // being forwarded to Carol, so Bob never keeps the parameters in-memory for more than a brief
cannam@132 132 // period. However, the flow limit counts all calls that haven't returned, even if Bob has
cannam@132 133 // already freed the memory they consumed. You might argue that the right solution here is
cannam@132 134 // instead for Carol to impose her own flow limit on Bob. This has a serious problem, though:
cannam@132 135 // Bob might be forwarding requests to Carol on behalf of many different parties, not just Alice.
cannam@132 136 // If Alice can pump enough data to hit the Bob -> Carol flow limit, then those other parties
cannam@132 137 // will be disrupted. Thus, we can only really impose the limit on the Alice -> Bob link, which
cannam@132 138 // only affects Alice. We need that one flow limit to limit Alice's impact on the whole system,
cannam@132 139 // so it has to count all in-flight calls.
cannam@132 140 //
cannam@132 141 // In Sandstorm, flow limits are imposed by the supervisor on calls coming out of a grain, in
cannam@132 142 // order to prevent a grain from inundating the system with in-flight calls. In practice, the
cannam@132 143 // main time this happens is when a grain is pushing a large file download and doesn't implement
cannam@132 144 // proper cooperative flow control.
cannam@132 145 };
cannam@132 146
cannam@132 147 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 148 typename ThirdPartyCapId, typename JoinResult>
cannam@132 149 RpcSystem<VatId> makeRpcServer(
cannam@132 150 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 151 Capability::Client bootstrapInterface);
cannam@132 152 // Make an RPC server. Typical usage (e.g. in a main() function):
cannam@132 153 //
cannam@132 154 // MyEventLoop eventLoop;
cannam@132 155 // kj::WaitScope waitScope(eventLoop);
cannam@132 156 // MyNetwork network;
cannam@132 157 // MyMainInterface::Client bootstrap = makeMain();
cannam@132 158 // auto server = makeRpcServer(network, bootstrap);
cannam@132 159 // kj::NEVER_DONE.wait(waitScope); // run forever
cannam@132 160 //
cannam@132 161 // See also ez-rpc.h, which has simpler instructions for the common case of a two-party
cannam@132 162 // client-server RPC connection.
cannam@132 163
cannam@132 164 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 165 typename ThirdPartyCapId, typename JoinResult, typename RealmGatewayClient,
cannam@132 166 typename InternalRef = _::InternalRefFromRealmGatewayClient<RealmGatewayClient>,
cannam@132 167 typename ExternalRef = _::ExternalRefFromRealmGatewayClient<RealmGatewayClient>>
cannam@132 168 RpcSystem<VatId> makeRpcServer(
cannam@132 169 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 170 Capability::Client bootstrapInterface, RealmGatewayClient gateway);
cannam@132 171 // Make an RPC server for a VatNetwork that resides in a different realm from the application.
cannam@132 172 // The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format
cannam@132 173 // and the network's ("external") format.
cannam@132 174
cannam@132 175 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 176 typename ThirdPartyCapId, typename JoinResult>
cannam@132 177 RpcSystem<VatId> makeRpcServer(
cannam@132 178 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 179 BootstrapFactory<VatId>& bootstrapFactory);
cannam@132 180 // Make an RPC server that can serve different bootstrap interfaces to different clients via a
cannam@132 181 // BootstrapInterface.
cannam@132 182
cannam@132 183 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 184 typename ThirdPartyCapId, typename JoinResult, typename RealmGatewayClient,
cannam@132 185 typename InternalRef = _::InternalRefFromRealmGatewayClient<RealmGatewayClient>,
cannam@132 186 typename ExternalRef = _::ExternalRefFromRealmGatewayClient<RealmGatewayClient>>
cannam@132 187 RpcSystem<VatId> makeRpcServer(
cannam@132 188 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 189 BootstrapFactory<VatId>& bootstrapFactory, RealmGatewayClient gateway);
cannam@132 190 // Make an RPC server that can serve different bootstrap interfaces to different clients via a
cannam@132 191 // BootstrapInterface and communicates with a different realm than the application is in via a
cannam@132 192 // RealmGateway.
cannam@132 193
cannam@132 194 template <typename VatId, typename LocalSturdyRefObjectId,
cannam@132 195 typename ProvisionId, typename RecipientId, typename ThirdPartyCapId, typename JoinResult>
cannam@132 196 RpcSystem<VatId> makeRpcServer(
cannam@132 197 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 198 SturdyRefRestorer<LocalSturdyRefObjectId>& restorer)
cannam@132 199 KJ_DEPRECATED("Please transition to using a bootstrap interface instead.");
cannam@132 200 // ** DEPRECATED **
cannam@132 201 //
cannam@132 202 // Create an RPC server which exports multiple main interfaces by object ID. The `restorer` object
cannam@132 203 // can be used to look up objects by ID.
cannam@132 204 //
cannam@132 205 // Please transition to exporting only one interface, which is known as the "bootstrap" interface.
cannam@132 206 // For backwards-compatibility with old clients, continue to implement SturdyRefRestorer, but
cannam@132 207 // return the new bootstrap interface when the request object ID is null. When new clients connect
cannam@132 208 // and request the bootstrap interface, they will get that interface. Eventually, once all clients
cannam@132 209 // are updated to request only the bootstrap interface, stop implementing SturdyRefRestorer and
cannam@132 210 // switch to passing the bootstrap capability itself as the second parameter to `makeRpcServer()`.
cannam@132 211
cannam@132 212 template <typename VatId, typename ProvisionId,
cannam@132 213 typename RecipientId, typename ThirdPartyCapId, typename JoinResult>
cannam@132 214 RpcSystem<VatId> makeRpcClient(
cannam@132 215 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network);
cannam@132 216 // Make an RPC client. Typical usage (e.g. in a main() function):
cannam@132 217 //
cannam@132 218 // MyEventLoop eventLoop;
cannam@132 219 // kj::WaitScope waitScope(eventLoop);
cannam@132 220 // MyNetwork network;
cannam@132 221 // auto client = makeRpcClient(network);
cannam@132 222 // MyCapability::Client cap = client.restore(hostId, objId).castAs<MyCapability>();
cannam@132 223 // auto response = cap.fooRequest().send().wait(waitScope);
cannam@132 224 // handleMyResponse(response);
cannam@132 225 //
cannam@132 226 // See also ez-rpc.h, which has simpler instructions for the common case of a two-party
cannam@132 227 // client-server RPC connection.
cannam@132 228
cannam@132 229 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 230 typename ThirdPartyCapId, typename JoinResult, typename RealmGatewayClient,
cannam@132 231 typename InternalRef = _::InternalRefFromRealmGatewayClient<RealmGatewayClient>,
cannam@132 232 typename ExternalRef = _::ExternalRefFromRealmGatewayClient<RealmGatewayClient>>
cannam@132 233 RpcSystem<VatId> makeRpcClient(
cannam@132 234 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 235 RealmGatewayClient gateway);
cannam@132 236 // Make an RPC client for a VatNetwork that resides in a different realm from the application.
cannam@132 237 // The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format
cannam@132 238 // and the network's ("external") format.
cannam@132 239
cannam@132 240 template <typename SturdyRefObjectId>
cannam@132 241 class SturdyRefRestorer: public _::SturdyRefRestorerBase {
cannam@132 242 // ** DEPRECATED **
cannam@132 243 //
cannam@132 244 // In Cap'n Proto 0.4.x, applications could export multiple main interfaces identified by
cannam@132 245 // object IDs. The callback used to map object IDs to objects was `SturdyRefRestorer`, as we
cannam@132 246 // imagined this would eventually be used for restoring SturdyRefs as well. In practice, it was
cannam@132 247 // never used for real SturdyRefs, only for exporting singleton objects under well-known names.
cannam@132 248 //
cannam@132 249 // The new preferred strategy is to export only a _single_ such interface, called the
cannam@132 250 // "bootstrap interface". That interface can itself have methods for obtaining other objects, of
cannam@132 251 // course, but that is up to the app. `SturdyRefRestorer` exists for backwards-compatibility.
cannam@132 252 //
cannam@132 253 // Hint: Use SturdyRefRestorer<capnp::Text> to define a server that exports services under
cannam@132 254 // string names.
cannam@132 255
cannam@132 256 public:
cannam@132 257 virtual Capability::Client restore(typename SturdyRefObjectId::Reader ref)
cannam@132 258 KJ_DEPRECATED(
cannam@132 259 "Please transition to using bootstrap interfaces instead of SturdyRefRestorer.") = 0;
cannam@132 260 // Restore the given object, returning a capability representing it.
cannam@132 261
cannam@132 262 private:
cannam@132 263 Capability::Client baseRestore(AnyPointer::Reader ref) override final;
cannam@132 264 };
cannam@132 265
cannam@132 266 // =======================================================================================
cannam@132 267 // VatNetwork
cannam@132 268
cannam@132 269 class OutgoingRpcMessage {
cannam@132 270 // A message to be sent by a `VatNetwork`.
cannam@132 271
cannam@132 272 public:
cannam@132 273 virtual AnyPointer::Builder getBody() = 0;
cannam@132 274 // Get the message body, which the caller may fill in any way it wants. (The standard RPC
cannam@132 275 // implementation initializes it as a Message as defined in rpc.capnp.)
cannam@132 276
cannam@132 277 virtual void send() = 0;
cannam@132 278 // Send the message, or at least put it in a queue to be sent later. Note that the builder
cannam@132 279 // returned by `getBody()` remains valid at least until the `OutgoingRpcMessage` is destroyed.
cannam@132 280 };
cannam@132 281
cannam@132 282 class IncomingRpcMessage {
cannam@132 283 // A message received from a `VatNetwork`.
cannam@132 284
cannam@132 285 public:
cannam@132 286 virtual AnyPointer::Reader getBody() = 0;
cannam@132 287 // Get the message body, to be interpreted by the caller. (The standard RPC implementation
cannam@132 288 // interprets it as a Message as defined in rpc.capnp.)
cannam@132 289 };
cannam@132 290
cannam@132 291 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 292 typename ThirdPartyCapId, typename JoinResult>
cannam@132 293 class VatNetwork: public _::VatNetworkBase {
cannam@132 294 // Cap'n Proto RPC operates between vats, where a "vat" is some sort of host of objects.
cannam@132 295 // Typically one Cap'n Proto process (in the Unix sense) is one vat. The RPC system is what
cannam@132 296 // allows calls between objects hosted in different vats.
cannam@132 297 //
cannam@132 298 // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork`
cannam@132 299 // determines how to form connections between vats -- specifically, two-way, private, reliable,
cannam@132 300 // sequenced datagram connections. The RPC implementation determines how to use such connections
cannam@132 301 // to manage object references and make method calls.
cannam@132 302 //
cannam@132 303 // The most common implementation of VatNetwork is TwoPartyVatNetwork (rpc-twoparty.h). Most
cannam@132 304 // simple client-server apps will want to use it. (You may even want to use the EZ RPC
cannam@132 305 // interfaces in `ez-rpc.h` and avoid all of this.)
cannam@132 306 //
cannam@132 307 // TODO(someday): Provide a standard implementation for the public internet.
cannam@132 308
cannam@132 309 public:
cannam@132 310 class Connection;
cannam@132 311
cannam@132 312 struct ConnectionAndProvisionId {
cannam@132 313 // Result of connecting to a vat introduced by another vat.
cannam@132 314
cannam@132 315 kj::Own<Connection> connection;
cannam@132 316 // Connection to the new vat.
cannam@132 317
cannam@132 318 kj::Own<OutgoingRpcMessage> firstMessage;
cannam@132 319 // An already-allocated `OutgoingRpcMessage` associated with `connection`. The RPC system will
cannam@132 320 // construct this as an `Accept` message and send it.
cannam@132 321
cannam@132 322 Orphan<ProvisionId> provisionId;
cannam@132 323 // A `ProvisionId` already allocated inside `firstMessage`, which the RPC system will use to
cannam@132 324 // build the `Accept` message.
cannam@132 325 };
cannam@132 326
cannam@132 327 class Connection: public _::VatNetworkBase::Connection {
cannam@132 328 // A two-way RPC connection.
cannam@132 329 //
cannam@132 330 // This object may represent a connection that doesn't exist yet, but is expected to exist
cannam@132 331 // in the future. In this case, sent messages will automatically be queued and sent once the
cannam@132 332 // connection is ready, so that the caller doesn't need to know the difference.
cannam@132 333
cannam@132 334 public:
cannam@132 335 // Level 0 features ----------------------------------------------
cannam@132 336
cannam@132 337 virtual typename VatId::Reader getPeerVatId() = 0;
cannam@132 338 // Returns the connected vat's authenticated VatId. It is the VatNetwork's responsibility to
cannam@132 339 // authenticate this, so that the caller can be assured that they are really talking to the
cannam@132 340 // identified vat and not an imposter.
cannam@132 341
cannam@132 342 virtual kj::Own<OutgoingRpcMessage> newOutgoingMessage(uint firstSegmentWordSize) override = 0;
cannam@132 343 // Allocate a new message to be sent on this connection.
cannam@132 344 //
cannam@132 345 // If `firstSegmentWordSize` is non-zero, it should be treated as a hint suggesting how large
cannam@132 346 // to make the first segment. This is entirely a hint and the connection may adjust it up or
cannam@132 347 // down. If it is zero, the connection should choose the size itself.
cannam@132 348
cannam@132 349 virtual kj::Promise<kj::Maybe<kj::Own<IncomingRpcMessage>>> receiveIncomingMessage() override = 0;
cannam@132 350 // Wait for a message to be received and return it. If the read stream cleanly terminates,
cannam@132 351 // return null. If any other problem occurs, throw an exception.
cannam@132 352
cannam@132 353 virtual kj::Promise<void> shutdown() override KJ_WARN_UNUSED_RESULT = 0;
cannam@132 354 // Waits until all outgoing messages have been sent, then shuts down the outgoing stream. The
cannam@132 355 // returned promise resolves after shutdown is complete.
cannam@132 356
cannam@132 357 private:
cannam@132 358 AnyStruct::Reader baseGetPeerVatId() override;
cannam@132 359 };
cannam@132 360
cannam@132 361 // Level 0 features ------------------------------------------------
cannam@132 362
cannam@132 363 virtual kj::Maybe<kj::Own<Connection>> connect(typename VatId::Reader hostId) = 0;
cannam@132 364 // Connect to a VatId. Note that this method immediately returns a `Connection`, even
cannam@132 365 // if the network connection has not yet been established. Messages can be queued to this
cannam@132 366 // connection and will be delivered once it is open. The caller must attempt to read from the
cannam@132 367 // connection to verify that it actually succeeded; the read will fail if the connection
cannam@132 368 // couldn't be opened. Some network implementations may actually start sending messages before
cannam@132 369 // hearing back from the server at all, to avoid a round trip.
cannam@132 370 //
cannam@132 371 // Returns nullptr if `hostId` refers to the local host.
cannam@132 372
cannam@132 373 virtual kj::Promise<kj::Own<Connection>> accept() = 0;
cannam@132 374 // Wait for the next incoming connection and return it.
cannam@132 375
cannam@132 376 // Level 4 features ------------------------------------------------
cannam@132 377 // TODO(someday)
cannam@132 378
cannam@132 379 private:
cannam@132 380 kj::Maybe<kj::Own<_::VatNetworkBase::Connection>>
cannam@132 381 baseConnect(AnyStruct::Reader hostId) override final;
cannam@132 382 kj::Promise<kj::Own<_::VatNetworkBase::Connection>> baseAccept() override final;
cannam@132 383 };
cannam@132 384
cannam@132 385 // =======================================================================================
cannam@132 386 // ***************************************************************************************
cannam@132 387 // Inline implementation details start here
cannam@132 388 // ***************************************************************************************
cannam@132 389 // =======================================================================================
cannam@132 390
cannam@132 391 template <typename VatId>
cannam@132 392 Capability::Client BootstrapFactory<VatId>::baseCreateFor(AnyStruct::Reader clientId) {
cannam@132 393 return createFor(clientId.as<VatId>());
cannam@132 394 }
cannam@132 395
cannam@132 396 template <typename SturdyRef, typename ProvisionId, typename RecipientId,
cannam@132 397 typename ThirdPartyCapId, typename JoinResult>
cannam@132 398 kj::Maybe<kj::Own<_::VatNetworkBase::Connection>>
cannam@132 399 VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::
cannam@132 400 baseConnect(AnyStruct::Reader ref) {
cannam@132 401 auto maybe = connect(ref.as<SturdyRef>());
cannam@132 402 return maybe.map([](kj::Own<Connection>& conn) -> kj::Own<_::VatNetworkBase::Connection> {
cannam@132 403 return kj::mv(conn);
cannam@132 404 });
cannam@132 405 }
cannam@132 406
cannam@132 407 template <typename SturdyRef, typename ProvisionId, typename RecipientId,
cannam@132 408 typename ThirdPartyCapId, typename JoinResult>
cannam@132 409 kj::Promise<kj::Own<_::VatNetworkBase::Connection>>
cannam@132 410 VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::baseAccept() {
cannam@132 411 return accept().then(
cannam@132 412 [](kj::Own<Connection>&& connection) -> kj::Own<_::VatNetworkBase::Connection> {
cannam@132 413 return kj::mv(connection);
cannam@132 414 });
cannam@132 415 }
cannam@132 416
cannam@132 417 template <typename SturdyRef, typename ProvisionId, typename RecipientId,
cannam@132 418 typename ThirdPartyCapId, typename JoinResult>
cannam@132 419 AnyStruct::Reader VatNetwork<
cannam@132 420 SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::
cannam@132 421 Connection::baseGetPeerVatId() {
cannam@132 422 return getPeerVatId();
cannam@132 423 }
cannam@132 424
cannam@132 425 template <typename SturdyRef>
cannam@132 426 Capability::Client SturdyRefRestorer<SturdyRef>::baseRestore(AnyPointer::Reader ref) {
cannam@132 427 #pragma GCC diagnostic push
cannam@132 428 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
cannam@132 429 return restore(ref.getAs<SturdyRef>());
cannam@132 430 #pragma GCC diagnostic pop
cannam@132 431 }
cannam@132 432
cannam@132 433 template <typename VatId>
cannam@132 434 template <typename ProvisionId, typename RecipientId,
cannam@132 435 typename ThirdPartyCapId, typename JoinResult>
cannam@132 436 RpcSystem<VatId>::RpcSystem(
cannam@132 437 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 438 kj::Maybe<Capability::Client> bootstrap,
cannam@132 439 kj::Maybe<RealmGateway<>::Client> gateway)
cannam@132 440 : _::RpcSystemBase(network, kj::mv(bootstrap), kj::mv(gateway)) {}
cannam@132 441
cannam@132 442 template <typename VatId>
cannam@132 443 template <typename ProvisionId, typename RecipientId,
cannam@132 444 typename ThirdPartyCapId, typename JoinResult>
cannam@132 445 RpcSystem<VatId>::RpcSystem(
cannam@132 446 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 447 BootstrapFactory<VatId>& bootstrapFactory,
cannam@132 448 kj::Maybe<RealmGateway<>::Client> gateway)
cannam@132 449 : _::RpcSystemBase(network, bootstrapFactory, kj::mv(gateway)) {}
cannam@132 450
cannam@132 451 template <typename VatId>
cannam@132 452 template <typename ProvisionId, typename RecipientId,
cannam@132 453 typename ThirdPartyCapId, typename JoinResult,
cannam@132 454 typename LocalSturdyRefObjectId>
cannam@132 455 RpcSystem<VatId>::RpcSystem(
cannam@132 456 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 457 SturdyRefRestorer<LocalSturdyRefObjectId>& restorer)
cannam@132 458 : _::RpcSystemBase(network, restorer) {}
cannam@132 459
cannam@132 460 template <typename VatId>
cannam@132 461 Capability::Client RpcSystem<VatId>::bootstrap(typename VatId::Reader vatId) {
cannam@132 462 return baseBootstrap(_::PointerHelpers<VatId>::getInternalReader(vatId));
cannam@132 463 }
cannam@132 464
cannam@132 465 template <typename VatId>
cannam@132 466 Capability::Client RpcSystem<VatId>::restore(
cannam@132 467 typename VatId::Reader hostId, AnyPointer::Reader objectId) {
cannam@132 468 return baseRestore(_::PointerHelpers<VatId>::getInternalReader(hostId), objectId);
cannam@132 469 }
cannam@132 470
cannam@132 471 template <typename VatId>
cannam@132 472 inline void RpcSystem<VatId>::setFlowLimit(size_t words) {
cannam@132 473 baseSetFlowLimit(words);
cannam@132 474 }
cannam@132 475
cannam@132 476 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 477 typename ThirdPartyCapId, typename JoinResult>
cannam@132 478 RpcSystem<VatId> makeRpcServer(
cannam@132 479 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 480 Capability::Client bootstrapInterface) {
cannam@132 481 return RpcSystem<VatId>(network, kj::mv(bootstrapInterface));
cannam@132 482 }
cannam@132 483
cannam@132 484 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 485 typename ThirdPartyCapId, typename JoinResult,
cannam@132 486 typename RealmGatewayClient, typename InternalRef, typename ExternalRef>
cannam@132 487 RpcSystem<VatId> makeRpcServer(
cannam@132 488 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 489 Capability::Client bootstrapInterface, RealmGatewayClient gateway) {
cannam@132 490 return RpcSystem<VatId>(network, kj::mv(bootstrapInterface),
cannam@132 491 gateway.template castAs<RealmGateway<>>());
cannam@132 492 }
cannam@132 493
cannam@132 494 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 495 typename ThirdPartyCapId, typename JoinResult>
cannam@132 496 RpcSystem<VatId> makeRpcServer(
cannam@132 497 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 498 BootstrapFactory<VatId>& bootstrapFactory) {
cannam@132 499 return RpcSystem<VatId>(network, bootstrapFactory);
cannam@132 500 }
cannam@132 501
cannam@132 502 template <typename VatId, typename ProvisionId, typename RecipientId,
cannam@132 503 typename ThirdPartyCapId, typename JoinResult,
cannam@132 504 typename RealmGatewayClient, typename InternalRef, typename ExternalRef>
cannam@132 505 RpcSystem<VatId> makeRpcServer(
cannam@132 506 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 507 BootstrapFactory<VatId>& bootstrapFactory, RealmGatewayClient gateway) {
cannam@132 508 return RpcSystem<VatId>(network, bootstrapFactory, gateway.template castAs<RealmGateway<>>());
cannam@132 509 }
cannam@132 510
cannam@132 511 template <typename VatId, typename LocalSturdyRefObjectId,
cannam@132 512 typename ProvisionId, typename RecipientId, typename ThirdPartyCapId, typename JoinResult>
cannam@132 513 RpcSystem<VatId> makeRpcServer(
cannam@132 514 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 515 SturdyRefRestorer<LocalSturdyRefObjectId>& restorer) {
cannam@132 516 return RpcSystem<VatId>(network, restorer);
cannam@132 517 }
cannam@132 518
cannam@132 519 template <typename VatId, typename ProvisionId,
cannam@132 520 typename RecipientId, typename ThirdPartyCapId, typename JoinResult>
cannam@132 521 RpcSystem<VatId> makeRpcClient(
cannam@132 522 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network) {
cannam@132 523 return RpcSystem<VatId>(network, nullptr);
cannam@132 524 }
cannam@132 525
cannam@132 526 template <typename VatId, typename ProvisionId,
cannam@132 527 typename RecipientId, typename ThirdPartyCapId, typename JoinResult,
cannam@132 528 typename RealmGatewayClient, typename InternalRef, typename ExternalRef>
cannam@132 529 RpcSystem<VatId> makeRpcClient(
cannam@132 530 VatNetwork<VatId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
cannam@132 531 RealmGatewayClient gateway) {
cannam@132 532 return RpcSystem<VatId>(network, nullptr, gateway.template castAs<RealmGateway<>>());
cannam@132 533 }
cannam@132 534
cannam@132 535 } // namespace capnp
cannam@132 536
cannam@132 537 #endif // CAPNP_RPC_H_