Mercurial > hg > sv-dependency-builds
comparison win32-mingw/include/capnp/rpc-twoparty.h @ 50:37d53a7e8262
Headers for KJ/Capnp Win32
author | Chris Cannam |
---|---|
date | Wed, 26 Oct 2016 13:18:45 +0100 |
parents | |
children | eccd51b72864 |
comparison
equal
deleted
inserted
replaced
49:3ab5a40c4e3b | 50:37d53a7e8262 |
---|---|
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors | |
2 // Licensed under the MIT License: | |
3 // | |
4 // Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 // of this software and associated documentation files (the "Software"), to deal | |
6 // in the Software without restriction, including without limitation the rights | |
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 // copies of the Software, and to permit persons to whom the Software is | |
9 // furnished to do so, subject to the following conditions: | |
10 // | |
11 // The above copyright notice and this permission notice shall be included in | |
12 // all copies or substantial portions of the Software. | |
13 // | |
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
20 // THE SOFTWARE. | |
21 | |
22 #ifndef CAPNP_RPC_TWOPARTY_H_ | |
23 #define CAPNP_RPC_TWOPARTY_H_ | |
24 | |
25 #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) | |
26 #pragma GCC system_header | |
27 #endif | |
28 | |
29 #include "rpc.h" | |
30 #include "message.h" | |
31 #include <kj/async-io.h> | |
32 #include <capnp/rpc-twoparty.capnp.h> | |
33 | |
34 namespace capnp { | |
35 | |
36 namespace rpc { | |
37 namespace twoparty { | |
38 typedef VatId SturdyRefHostId; // For backwards-compatibility with version 0.4. | |
39 } | |
40 } | |
41 | |
42 typedef VatNetwork<rpc::twoparty::VatId, rpc::twoparty::ProvisionId, | |
43 rpc::twoparty::RecipientId, rpc::twoparty::ThirdPartyCapId, rpc::twoparty::JoinResult> | |
44 TwoPartyVatNetworkBase; | |
45 | |
46 class TwoPartyVatNetwork: public TwoPartyVatNetworkBase, | |
47 private TwoPartyVatNetworkBase::Connection { | |
48 // A `VatNetwork` that consists of exactly two parties communicating over an arbitrary byte | |
49 // stream. This is used to implement the common case of a client/server network. | |
50 // | |
51 // See `ez-rpc.h` for a simple interface for setting up two-party clients and servers. | |
52 // Use `TwoPartyVatNetwork` only if you need the advanced features. | |
53 | |
54 public: | |
55 TwoPartyVatNetwork(kj::AsyncIoStream& stream, rpc::twoparty::Side side, | |
56 ReaderOptions receiveOptions = ReaderOptions()); | |
57 KJ_DISALLOW_COPY(TwoPartyVatNetwork); | |
58 | |
59 kj::Promise<void> onDisconnect() { return disconnectPromise.addBranch(); } | |
60 // Returns a promise that resolves when the peer disconnects. | |
61 | |
62 rpc::twoparty::Side getSide() { return side; } | |
63 | |
64 // implements VatNetwork ----------------------------------------------------- | |
65 | |
66 kj::Maybe<kj::Own<TwoPartyVatNetworkBase::Connection>> connect( | |
67 rpc::twoparty::VatId::Reader ref) override; | |
68 kj::Promise<kj::Own<TwoPartyVatNetworkBase::Connection>> accept() override; | |
69 | |
70 private: | |
71 class OutgoingMessageImpl; | |
72 class IncomingMessageImpl; | |
73 | |
74 kj::AsyncIoStream& stream; | |
75 rpc::twoparty::Side side; | |
76 MallocMessageBuilder peerVatId; | |
77 ReaderOptions receiveOptions; | |
78 bool accepted = false; | |
79 | |
80 kj::Maybe<kj::Promise<void>> previousWrite; | |
81 // Resolves when the previous write completes. This effectively serves as the write queue. | |
82 // Becomes null when shutdown() is called. | |
83 | |
84 kj::Own<kj::PromiseFulfiller<kj::Own<TwoPartyVatNetworkBase::Connection>>> acceptFulfiller; | |
85 // Fulfiller for the promise returned by acceptConnectionAsRefHost() on the client side, or the | |
86 // second call on the server side. Never fulfilled, because there is only one connection. | |
87 | |
88 kj::ForkedPromise<void> disconnectPromise = nullptr; | |
89 | |
90 class FulfillerDisposer: public kj::Disposer { | |
91 // Hack: TwoPartyVatNetwork is both a VatNetwork and a VatNetwork::Connection. When the RPC | |
92 // system detects (or initiates) a disconnection, it drops its reference to the Connection. | |
93 // When all references have been dropped, then we want disconnectPromise to be fulfilled. | |
94 // So we hand out Own<Connection>s with this disposer attached, so that we can detect when | |
95 // they are dropped. | |
96 | |
97 public: | |
98 mutable kj::Own<kj::PromiseFulfiller<void>> fulfiller; | |
99 mutable uint refcount = 0; | |
100 | |
101 void disposeImpl(void* pointer) const override; | |
102 }; | |
103 FulfillerDisposer disconnectFulfiller; | |
104 | |
105 kj::Own<TwoPartyVatNetworkBase::Connection> asConnection(); | |
106 // Returns a pointer to this with the disposer set to disconnectFulfiller. | |
107 | |
108 // implements Connection ----------------------------------------------------- | |
109 | |
110 rpc::twoparty::VatId::Reader getPeerVatId() override; | |
111 kj::Own<OutgoingRpcMessage> newOutgoingMessage(uint firstSegmentWordSize) override; | |
112 kj::Promise<kj::Maybe<kj::Own<IncomingRpcMessage>>> receiveIncomingMessage() override; | |
113 kj::Promise<void> shutdown() override; | |
114 }; | |
115 | |
116 class TwoPartyServer: private kj::TaskSet::ErrorHandler { | |
117 // Convenience class which implements a simple server which accepts connections on a listener | |
118 // socket and serices them as two-party connections. | |
119 | |
120 public: | |
121 explicit TwoPartyServer(Capability::Client bootstrapInterface); | |
122 | |
123 void accept(kj::Own<kj::AsyncIoStream>&& connection); | |
124 // Accepts the connection for servicing. | |
125 | |
126 kj::Promise<void> listen(kj::ConnectionReceiver& listener); | |
127 // Listens for connections on the given listener. The returned promise never resolves unless an | |
128 // exception is thrown while trying to accept. You may discard the returned promise to cancel | |
129 // listening. | |
130 | |
131 private: | |
132 Capability::Client bootstrapInterface; | |
133 kj::TaskSet tasks; | |
134 | |
135 struct AcceptedConnection; | |
136 | |
137 void taskFailed(kj::Exception&& exception) override; | |
138 }; | |
139 | |
140 class TwoPartyClient { | |
141 // Convenience class which implements a simple client. | |
142 | |
143 public: | |
144 explicit TwoPartyClient(kj::AsyncIoStream& connection); | |
145 TwoPartyClient(kj::AsyncIoStream& connection, Capability::Client bootstrapInterface, | |
146 rpc::twoparty::Side side = rpc::twoparty::Side::CLIENT); | |
147 | |
148 Capability::Client bootstrap(); | |
149 // Get the server's bootstrap interface. | |
150 | |
151 inline kj::Promise<void> onDisconnect() { return network.onDisconnect(); } | |
152 | |
153 private: | |
154 TwoPartyVatNetwork network; | |
155 RpcSystem<rpc::twoparty::VatId> rpcSystem; | |
156 }; | |
157 | |
158 } // namespace capnp | |
159 | |
160 #endif // CAPNP_RPC_TWOPARTY_H_ |