5 #ifndef _XDRPP_ARPC_H_HEADER_INCLUDED_ 6 #define _XDRPP_ARPC_H_HEADER_INCLUDED_ 1 16 template<
typename T>
struct call_result : std::unique_ptr<T> {
22 call_result(rpc_call_stat::stat_type type) : stat_(type) {}
23 const char *message()
const {
return *
this ? nullptr : stat_.message(); }
28 call_result(rpc_call_stat::stat_type type) : stat_(type) {}
29 const char *message()
const {
return stat_ ? nullptr : stat_.message(); }
30 explicit operator bool()
const {
return bool(stat_); }
41 template<
typename P,
typename...A>
42 void invoke(
const A &...a,
44 rpc_msg hdr { s_.get_xid(), CALL };
45 hdr.body.cbody().rpcvers = 2;
46 hdr.body.cbody().prog = P::interface_type::program;
47 hdr.body.cbody().vers = P::interface_type::version;
48 hdr.body.cbody().proc = P::proc;
50 if (xdr_trace_client) {
51 std::string s =
"CALL ";
54 s += std::to_string(hdr.xid);
59 s_.send_call(
xdr_to_msg(hdr, a...), [cb](msg_ptr m) {
61 return cb(rpc_call_stat::NETWORK_ERROR);
66 call_result<typename P::res_type> res(hdr);
71 if (xdr_trace_client) {
72 std::string s =
"REPLY ";
74 s +=
" <- [xid " + std::to_string(hdr.xid) +
"]";
76 std::clog << xdr_to_string(*res, s.c_str());
88 cb(rpc_call_stat::GARBAGE_RES);
96 template<
typename T>
using arpc_client =
97 typename T::template _xdr_client<asynchronous_client_base>;
105 class reply_cb_impl {
107 using cb_t = service_base::cb_t;
110 const char *
const proc_name_;
113 template<
typename CB> reply_cb_impl(uint32_t xid, CB &&cb,
const char *name)
114 : xid_(xid), cb_(
std::forward<CB>(cb)), proc_name_(name) {}
115 reply_cb_impl(
const reply_cb_impl &rcb) =
delete;
116 reply_cb_impl &operator=(
const reply_cb_impl &rcb) =
delete;
117 ~reply_cb_impl() {
if (cb_) reject(PROC_UNAVAIL); }
120 void send_reply_msg(msg_ptr &&b) {
126 template<
typename T>
void send_reply(
const T &t) {
127 if (xdr_trace_server) {
128 std::string s =
"REPLY ";
130 s +=
" -> [xid " + std::to_string(xid_) +
"]";
136 void reject(accept_stat stat) {
137 send_reply_msg(rpc_accepted_error_msg(xid_, stat));
139 void reject(auth_stat stat) {
140 send_reply_msg(rpc_auth_error_msg(xid_, stat));
148 template<
typename T>
class reply_cb {
149 using impl_t = detail::reply_cb_impl;
152 std::shared_ptr<impl_t> impl_;
155 template<
typename CB>
reply_cb(uint32_t xid, CB &&cb,
const char *name)
156 : impl_(
std::make_shared<impl_t>(xid,
std::forward<CB>(cb), name)) {}
158 void operator()(
const type &t)
const { impl_->send_reply(t); }
159 void reject(accept_stat stat)
const { impl_->reject(stat); }
160 void reject(auth_stat stat)
const { impl_->reject(stat); }
167 void operator()()
const { this->operator()(
xdr_void{}); }
170 template<
typename T,
typename Session,
typename Interface>
175 void process(
void *session,
rpc_msg &hdr,
xdr_get &g, cb_t reply)
override {
176 if (!check_call(hdr))
178 if (!Interface::call_dispatch(*
this, hdr.body.cbody().proc,
179 static_cast<Session *
>(session),
180 hdr, g, std::move(reply)))
181 reply(rpc_accepted_error_msg(hdr.xid, PROC_UNAVAIL));
185 void dispatch(Session *session,
rpc_msg &hdr,
xdr_get &g, cb_t reply) {
187 if (!decode_arg(g, arg))
188 return reply(rpc_accepted_error_msg(hdr.xid, GARBAGE_ARGS));
190 if (xdr_trace_server) {
191 std::string s =
"CALL ";
193 s +=
" <- [xid " + std::to_string(hdr.xid) +
"]";
197 dispatch_with_session<P>(server_, session, std::move(arg),
199 hdr.xid, std::move(reply), P::proc_name()});
209 template<
typename T,
typename Interface =
typename T::rpc_
interface_type>
210 void register_service(T &t) {
213 void receive(
rpc_sock *ms, msg_ptr buf);
216 template<
typename Session = void,
223 #endif // !_XDRPP_ARPC_H_HEADER_INCLUDED_ Structure that gets marshalled as an RPC success header.
std::tuple<> xdr_void
Placehoder type representing void values marshaled as 0 bytes.
A unique_ptr to a call result, or NULL if the call failed (in which case message returns an error mes...
Most of the xdrpp library is encapsulated in the xdr namespace.
Archive type for unmarshaling from a buffer.
msg_ptr xdr_to_msg(const Args &...args)
Marshal one or a series of XDR types into a newly allocated buffer referenced xdr::msg_ptr.
A wrapper around xdr::msg_sock that separates calls from replies.
Exceptions raised by RPC calls.
Generic class of XDR unmarshaling errors.
Classes for implementing RPC servers.
Trivial session allocator that just calls new and delete.
Simple synchronous RPC functions.
Structure encoding all the various reasons a server can decline to process an RPC call it received...
typename detail::wrap_transparent_ptr_helper< T >::type wrap_transparent_ptr
Wrap xdr::transparent_ptr around each type in a tuple to generate a new tuple type.
std::string xdr_to_string(const T &t, const char *name=nullptr, int indent=0)
Return a std::string containing a pretty-printed version an XDR data type.