doc
This commit is contained in:
@@ -146,6 +146,49 @@ the event queue
|
||||
.. doxygenstruct:: pvxs::client::Subscription
|
||||
:members:
|
||||
|
||||
Threading
|
||||
^^^^^^^^^
|
||||
|
||||
A client Context will invoke user callback functions from one or more internal worker threads.
|
||||
However, it is guaranteed that callbacks relating to a given Channel (PV name + priority) will never be executed concurrently.
|
||||
This implies that callbacks for a single operation will also never be executed concurrently.
|
||||
|
||||
User code must avoid doing unnecessary work from within a callback function as this will
|
||||
prevent other callbacks from be executed.
|
||||
|
||||
Ownership
|
||||
^^^^^^^^^
|
||||
|
||||
User provided callbacks are in the form of std::function which may,
|
||||
directly or indirectly, store shared_ptr<> instances.
|
||||
The returned Operation and Subscription instances may be treated as
|
||||
storing the std::function instance(s) and thus any shared_ptr<> captured in them.
|
||||
|
||||
Therefore, in order to avoid a resource leak,
|
||||
it is advisable to consider whether a returned Operation or Subscription
|
||||
may participate in a reference loop.
|
||||
|
||||
For example, the following creates a reference loop between the Operation instance and the "mystruct" instance.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
struct mystruct {
|
||||
std::shared_ptr<Operation> op; // <-- Danger!
|
||||
};
|
||||
auto myptr = std::make_shared<mystruct>();
|
||||
|
||||
Context ctxt(...);
|
||||
myptr->op = ctxt.get("pv:name")
|
||||
.result([ctxt](Result&& result) {
|
||||
})
|
||||
.exec();
|
||||
|
||||
While such loops can be explicitly broken (eg. by NULLing 'myptr->op') it is strongly
|
||||
recommended to avoid such situations as unexpected (exceptional) conditions can easily
|
||||
lead to resource leaks which are quite difficult to detect and isolate.
|
||||
|
||||
Where possible it is recommended to capture weak_ptr<> instances.
|
||||
|
||||
pvRequest
|
||||
---------
|
||||
|
||||
|
||||
+12
-1
@@ -3,7 +3,18 @@ PVXS client/server for PVA Protocol
|
||||
|
||||
This module is under active development and is only suitable for experimental usage.
|
||||
|
||||
The canonical source can be found at https://github.com/mdavidsaver/pvxs
|
||||
The canonical version of this page is https://mdavidsaver.github.io/pvxs
|
||||
|
||||
Versioned source can be found at https://github.com/mdavidsaver/pvxs
|
||||
|
||||
This module provides a library (libpvxs.so or pvxs.dll) and a set of
|
||||
CLI utilities acting as PVAccess protocol client and/or server.
|
||||
|
||||
Dependencies
|
||||
|
||||
* A C++11 compliant compiler (eg. GCC >= 4.9)
|
||||
* EPICS Base >=3.15.1
|
||||
* libevent >=2.0.1
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
+11
-2
@@ -99,6 +99,7 @@ struct PVXS_API Operation {
|
||||
virtual ~Operation() =0;
|
||||
|
||||
//! Explicitly cancel a pending operation.
|
||||
//! Blocks until an in-progress callback has completed.
|
||||
virtual void cancel() =0;
|
||||
};
|
||||
|
||||
@@ -108,6 +109,7 @@ struct PVXS_API Subscription {
|
||||
virtual ~Subscription() =0;
|
||||
|
||||
//! Explicitly cancel a active subscription.
|
||||
//! Blocks until any in-progress callback has completed.
|
||||
virtual void cancel() =0;
|
||||
|
||||
//! Ask a server to stop sending updates to this Subscription
|
||||
@@ -355,7 +357,8 @@ class GetBuilder : public detail::CommonBuilder<GetBuilder> {
|
||||
std::shared_ptr<Operation> _exec_get();
|
||||
public:
|
||||
GetBuilder(const std::shared_ptr<Context::Pvt>& ctx, const std::string& name, bool get) :CommonBuilder{ctx,name}, _get(get) {}
|
||||
//! Callback through which result Value or an error will be delivered
|
||||
//! Callback through which result Value or an error will be delivered.
|
||||
//! The functor is stored in the Operation returned by exec().
|
||||
GetBuilder& result(std::function<void(Result&&)>&& cb) { _result = std::move(cb); return *this; }
|
||||
|
||||
/** Execute the network operation.
|
||||
@@ -392,12 +395,16 @@ public:
|
||||
* Once the PV type information is received from the server,
|
||||
* this function will be responsible for populating a Value
|
||||
* which will actually be sent.
|
||||
*
|
||||
* The functor is stored in the Operation returned by exec().
|
||||
*/
|
||||
PutBuilder& build(std::function<Value(Value&&)>&& cb) { _builder = std::move(cb); return *this; }
|
||||
|
||||
/** Provide the operation result callback.
|
||||
* This callback will be passed a Result which is either an empty Value (success)
|
||||
* or an exception on error.
|
||||
*
|
||||
* The functor is stored in the Operation returned by exec().
|
||||
*/
|
||||
PutBuilder& result(std::function<void(Result&&)>&& cb) { _result = std::move(cb); return *this; }
|
||||
|
||||
@@ -418,7 +425,8 @@ class RPCBuilder : public detail::CommonBuilder<GetBuilder> {
|
||||
std::function<void(Result&&)> _result;
|
||||
public:
|
||||
RPCBuilder(const std::shared_ptr<Context::Pvt>& ctx, const std::string& name, Value&& arg) :CommonBuilder{ctx,name}, _argument(std::move(arg)) {}
|
||||
//! Callback through which result Value or an error will be delivered
|
||||
//! Callback through which result Value or an error will be delivered.
|
||||
//! The functor is stored in the Operation returned by exec().
|
||||
RPCBuilder& result(std::function<void(Result&&)>&& cb) { _result = std::move(cb); return *this; }
|
||||
|
||||
/** Execute the network operation.
|
||||
@@ -440,6 +448,7 @@ class MonitorBuilder : public detail::CommonBuilder<MonitorBuilder> {
|
||||
public:
|
||||
MonitorBuilder(const std::shared_ptr<Context::Pvt>& ctx, const std::string& name) :CommonBuilder{ctx,name} {}
|
||||
//! Install event callback
|
||||
//! The functor is stored in the Subscription returned by exec().
|
||||
MonitorBuilder& event(std::function<void(Subscription&)>&& cb) { _event = std::move(cb); return *this; }
|
||||
//! Include Connected exceptions in queue (default false).
|
||||
MonitorBuilder& maskConnected(bool m = true) { _maskConn = m; return *this; }
|
||||
|
||||
@@ -609,8 +609,19 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** Depth-first iteration of all decendent fields
|
||||
*
|
||||
* @code
|
||||
* Value top(...);
|
||||
* for(auto fld : top.iall()) {
|
||||
* std::cout<<top.nameOf(fld)<<" = "<<fld<<"\n";
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
Iterable<Value> iall() { return Iterable<Value>{this, false, true}; }
|
||||
//! iteration of all child fields
|
||||
Iterable<Value> ichildren() { return Iterable<Value>{this, false, false}; }
|
||||
//! Depth-first iteration of all marked decendent fields
|
||||
Iterable<Value> imarked() { return Iterable<Value>{this, true , true}; }
|
||||
|
||||
Iterable<const Value> iall() const { return Iterable<const Value>{this, false, true}; }
|
||||
|
||||
+8
-3
@@ -92,9 +92,14 @@ public:
|
||||
|
||||
virtual void stats(MonitorStat&) const =0;
|
||||
|
||||
//! Set flow control levels.
|
||||
//! onLowMark callback will be invoked when nFree()<=low becomes true, and not again until it has been false.
|
||||
//! onHighMark callback will be invoked when nFree()>high becomes true, and not again until it has been false.
|
||||
/** Set flow control levels.
|
||||
*
|
||||
* Flow control operations against an outbound "window" size, which is the number of updates which may
|
||||
* be sent before a client ack. must be received. By default both high and low levels are zero.
|
||||
*
|
||||
* onLowMark callback is not currently implemented and the 'low' level is not used.
|
||||
* onHighMark callback will be invoked when a client ack. increases the window size above (>) 'high'.
|
||||
*/
|
||||
virtual void setWatermarks(size_t low, size_t high) =0;
|
||||
|
||||
//! Callback when client resumes/pauses updates
|
||||
|
||||
Reference in New Issue
Block a user