@@ -60,8 +60,35 @@ class ProxyClientBase : public Impl_
60
60
ProxyClientBase (typename Interface::Client client, Connection* connection, bool destroy_connection);
61
61
~ProxyClientBase () noexcept ;
62
62
63
- // Methods called during client construction/destruction that can optionally
64
- // be defined in capnp interface to trigger the server.
63
+ // construct/destroy methods called during client construction/destruction
64
+ // that can optionally be defined in capnp interfaces to invoke code on the
65
+ // server when proxy client objects are created and destroyed.
66
+ //
67
+ // The construct() method is not generally very useful, but can be used to
68
+ // run custom code on the server automatically when a ProxyClient client is
69
+ // constructed. The only current use is adding a construct method to Init
70
+ // interfaces that is called automatically on construction, so client and
71
+ // server exchange ThreadMap references and set Connection::m_thread_map
72
+ // values as soon as the Init client is created.
73
+ //
74
+ // construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap: Proxy.ThreadMap);
75
+ //
76
+ // But construct() is not necessary for this, thread maps could be passed
77
+ // through a normal method that is just called explicitly rather than
78
+ // implicitly.
79
+ //
80
+ // The destroy() method is more generally useful than construct(), because
81
+ // it ensures that the server object will be destroyed synchronously before
82
+ // the client destructor returns, instead of asynchronously at some
83
+ // unpredictable time after the client object is already destroyed and
84
+ // client code has moved on. If the destroy method accepts a Context
85
+ // parameter like:
86
+ //
87
+ // destroy @0 (context: Proxy.Context) -> ();
88
+ //
89
+ // then it will also ensure that the destructor runs on the same thread the
90
+ // client used to make other RPC calls, instead of running on the server
91
+ // EventLoop thread and possibly blocking it.
65
92
void construct () {}
66
93
void destroy () {}
67
94
@@ -109,20 +136,52 @@ struct ProxyServerBase : public virtual Interface_::Server
109
136
ProxyContext m_context;
110
137
};
111
138
112
- // ! Customizable (through template specialization) base class used in generated ProxyServer implementations from
113
- // ! proxy-codegen.cpp.
139
+ // ! Customizable (through template specialization) base class which ProxyServer
140
+ // ! classes produced by generated code will inherit from. The default
141
+ // ! specialization of this class just inherits from ProxyServerBase, but custom
142
+ // ! specializations can be defined to control ProxyServer behavior.
143
+ // !
144
+ // ! Specifically, it can be useful to specialize this class to add additional
145
+ // ! state to ProxyServer classes, for example to cache state between IPC calls.
146
+ // ! If this is done, however, care should be taken to ensure that the extra
147
+ // ! state can be destroyed without blocking, because ProxyServer destructors are
148
+ // ! called from the EventLoop thread, and if they block, it could deadlock the
149
+ // ! program. One way to do avoid blocking is to clean up the state by pushing
150
+ // ! cleanup callbacks to the m_context.cleanup list, which run after the server
151
+ // ! m_impl object is destroyed on the same thread destroying it (which will
152
+ // ! either be an IPC worker thread if the ProxyServer is being explicitly
153
+ // ! destroyed by a client calling a destroy() method with a Context argument and
154
+ // ! Context.thread value set, or the temporary EventLoop::m_async_thread used to
155
+ // ! run destructors without blocking the event loop when no-longer used server
156
+ // ! objects are garbage collected by Cap'n Proto.) Alternately, if cleanup needs
157
+ // ! to run before m_impl is destroyed, the specialization can override
158
+ // ! invokeDestroy and destructor methods to do that.
114
159
template <typename Interface, typename Impl>
115
160
struct ProxyServerCustom : public ProxyServerBase <Interface, Impl>
116
161
{
117
162
using ProxyServerBase<Interface, Impl>::ProxyServerBase;
118
163
};
119
164
120
- // ! Function traits class used to get method parameter and result types in generated ProxyClient implementations from
121
- // ! proxy-codegen.cpp.
165
+ // ! Function traits class used to get method parameter and result types, used in
166
+ // ! generated ProxyClient and ProxyServer classes produced by gen.cpp to get C++
167
+ // ! method type information. The generated code accesses these traits via
168
+ // ! intermediate ProxyClientMethodTraits and ProxyServerMethodTraits classes,
169
+ // ! which it is possible to specialize to change the way method arguments and
170
+ // ! return values are handled.
171
+ // !
172
+ // ! Fields of the trait class are:
173
+ // !
174
+ // ! Params - TypeList of C++ ClassName::methodName parameter types
175
+ // ! Result - Return type of ClassName::method
176
+ // ! Param<N> - helper to access individual parameters by index number.
177
+ // ! Fields - helper alias that appends Result type to the Params typelist if
178
+ // ! it not void.
122
179
template <class Fn >
123
180
struct FunctionTraits ;
124
181
125
- // ! Specialization of above to extract result and params types.
182
+ // ! Specialization of above extracting result and params types assuming the
183
+ // ! template argument is a pointer-to-method type,
184
+ // ! decltype(&ClassName::methodName)
126
185
template <class _Class , class _Result , class ... _Params>
127
186
struct FunctionTraits <_Result (_Class::*const )(_Params...)>
128
187
{
@@ -134,16 +193,20 @@ struct FunctionTraits<_Result (_Class::*const)(_Params...)>
134
193
typename std::conditional<std::is_same<void , Result>::value, Params, TypeList<_Params..., _Result>>::type;
135
194
};
136
195
137
- // ! Traits class for a method specialized by method parameters.
138
- // !
139
- // ! Param and Result typedefs can be customized to adjust parameter and return types on client side.
196
+ // ! Traits class for a proxy method, providing the same
197
+ // ! Params/Result/Param/Fields described in the FunctionTraits class above, plus
198
+ // ! an additional invoke() method that calls the C++ method which is being
199
+ // ! proxied, forwarding any arguments.
140
200
// !
141
- // ! Invoke method customized to adjust parameter and return types on server side.
201
+ // ! The template argument should be the InterfaceName::MethodNameParams class
202
+ // ! (generated by Cap'n Proto) associated with the method.
142
203
// !
143
- // ! Normal method calls go through the ProxyMethodTraits struct specialization
144
- // ! below, not this default struct, which is only used if there is no
145
- // ! ProxyMethod::impl method pointer, which is only true for construct/destroy
146
- // ! methods.
204
+ // ! Note: The class definition here is just the fallback definition used when
205
+ // ! the other specialization below doesn't match. The fallback is only used for
206
+ // ! capnp methods which do not have corresponding C++ methods, which in practice
207
+ // ! is just the two special construct() and destroy() methods described in \ref
208
+ // ! ProxyClientBase. These methods don't have any C++ parameters or return
209
+ // ! types, so the trait information below reflects that.
147
210
template <typename MethodParams, typename Enable = void >
148
211
struct ProxyMethodTraits
149
212
{
@@ -157,7 +220,18 @@ struct ProxyMethodTraits
157
220
}
158
221
};
159
222
160
- // ! Specialization of above.
223
+ // ! Specialization of above for proxy methods that have a
224
+ // ! ProxyMethod<InterfaceName::MethodNameParams>::impl pointer-to-method
225
+ // ! constant defined by generated code. This includes all functions defined in
226
+ // ! the capnp interface except any construct() or destroy() methods, that are
227
+ // ! assumed not to correspond to real member functions in the C++ class, and
228
+ // ! will use the fallback traits definition above. The generated code this
229
+ // ! specialization relies on looks like:
230
+ // !
231
+ // ! struct ProxyMethod<InterfaceName::MethodNameParams>
232
+ // ! {
233
+ // ! static constexpr auto impl = &ClassName::methodName;
234
+ // ! };
161
235
template <typename MethodParams>
162
236
struct ProxyMethodTraits <MethodParams, Require<decltype (ProxyMethod<MethodParams>::impl)>>
163
237
: public FunctionTraits<decltype (ProxyMethod<MethodParams>::impl)>
0 commit comments