From 3dd4dd6a669a39c5c46f1da5d75f4c5e19ebaa87 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sat, 2 Jan 2021 14:43:25 -0800 Subject: [PATCH] client: different onInit() for monitor --- src/clientget.cpp | 2 +- src/clientmon.cpp | 4 ++-- src/pvxs/client.h | 26 +++++++++++++++++++------- test/testmon.cpp | 6 ++++-- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/clientget.cpp b/src/clientget.cpp index 87ab752..0e7d0ec 100644 --- a/src/clientget.cpp +++ b/src/clientget.cpp @@ -656,7 +656,7 @@ std::shared_ptr RPCBuilder::exec() auto context(ctx->impl->shared_from_this()); auto op(std::make_shared(Operation::RPC, context->tcp_loop)); - op->setDone(std::move(_result), std::move(_onInit)); + op->setDone(std::move(_result), nullptr); if(_argument) { if(!_autoexec) throw std::invalid_argument("Pass RPC argument during reExec()"); diff --git a/src/clientmon.cpp b/src/clientmon.cpp index e3c189b..d4f1aaf 100644 --- a/src/clientmon.cpp +++ b/src/clientmon.cpp @@ -40,7 +40,7 @@ struct SubscriptionImpl : public OperationBase, public Subscription // const after exec() std::weak_ptr self; // internal - std::function onInit; + std::function onInit; std::function event; Value pvRequest; bool pipeline = false; @@ -460,7 +460,7 @@ void Connection::handle_MONITOR() mon->chan->name.c_str()); if(mon->onInit) - mon->onInit(info->prototype); + mon->onInit(*mon, info->prototype); mon->state = SubscriptionImpl::Idle; diff --git a/src/pvxs/client.h b/src/pvxs/client.h index 29e7a1f..4c67f1b 100644 --- a/src/pvxs/client.h +++ b/src/pvxs/client.h @@ -516,7 +516,6 @@ protected: template class CommonBuilder : public Base { protected: - std::function _onInit; CommonBuilder() = default; constexpr CommonBuilder(const std::shared_ptr& ctx, const std::string& name) : Base(ctx, name) {} inline SubBuilder& _sb() { return static_cast(*this); } @@ -559,11 +558,6 @@ public: SubBuilder& priority(int p) { this->_prio = p; return _sb(); } SubBuilder& server(const std::string& s) { this->_server = s; return _sb(); } - // Expert API - // called during operation INIT phase for Get/Put/Monitor when remote type - // description is available. - SubBuilder& onInit(std::function&& cb) { this->_onInit = std::move(cb); return _sb(); } - // Expert API // for GET/PUT control whether operations automatically proceed from INIT to EXEC // cf. Operation::reExec() @@ -584,6 +578,7 @@ public: //! Prepare a remote GET or GET_FIELD (info) operation. //! See Context::get() class GetBuilder : public detail::CommonBuilder { + std::function _onInit; std::function _result; bool _get = false; PVXS_API @@ -597,6 +592,11 @@ public: //! The functor is stored in the Operation returned by exec(). GetBuilder& result(std::function&& cb) { _result = std::move(cb); return *this; } + // Expert API + // called during operation INIT phase for Get/Put/Monitor when remote type + // description is available. + GetBuilder& onInit(std::function&& cb) { this->_onInit = std::move(cb); return *this; } + /** Execute the network operation. * The caller must keep returned Operation pointer until completion * or the operation will be implicitly canceled. @@ -613,9 +613,10 @@ GetBuilder Context::get(const std::string& name) { return GetBuilder{pvt, name, //! Prepare a remote PUT operation //! See Context::put() class PutBuilder : public detail::CommonBuilder { - bool _doGet = true; + std::function _onInit; std::function _builder; std::function _result; + bool _doGet = true; public: PutBuilder() = default; PutBuilder(const std::shared_ptr& ctx, const std::string& name) :CommonBuilder{ctx,name} {} @@ -665,6 +666,11 @@ public: */ PutBuilder& result(std::function&& cb) { _result = std::move(cb); return *this; } + // Expert API + // called during operation INIT phase for Get/Put/Monitor when remote type + // description is available. + PutBuilder& onInit(std::function&& cb) { this->_onInit = std::move(cb); return *this; } + /** Execute the network operation. * The caller must keep returned Operation pointer until completion * or the operation will be implicitly canceled. @@ -726,6 +732,7 @@ RPCBuilder Context::rpc(const std::string& name, const Value &arg) { //! Prepare a remote subscription //! See Context::monitor() class MonitorBuilder : public detail::CommonBuilder { + std::function _onInit; std::function _event; bool _maskConn = true; bool _maskDisconn = false; @@ -746,6 +753,11 @@ public: //! Include Disconnected exceptions in queue (default true). MonitorBuilder& maskDisconnected(bool m = true) { _maskDisconn = m; return *this; } + // Expert API + // called during operation INIT phase for Get/Put/Monitor when remote type + // description is available. + MonitorBuilder& onInit(std::function&& cb) { this->_onInit = std::move(cb); return *this; } + //! Submit request to subscribe PVXS_API std::shared_ptr exec(); diff --git a/test/testmon.cpp b/test/testmon.cpp index 0bfb973..beaf3ba 100644 --- a/test/testmon.cpp +++ b/test/testmon.cpp @@ -102,7 +102,8 @@ struct BasicTest { epicsEvent done; cli.monitor("nonexistent") - .onInit([&done](const Value&) { + .onInit([&done](client::Subscription&, const Value&) + { done.signal(); }) .exec(); @@ -117,7 +118,8 @@ struct BasicTest { cli.monitor("nonexistent") .syncCancel(false) - .onInit([done](const Value&) { + .onInit([done](client::Subscription&, const Value&) + { done->signal(); }) .exec();