SharedPV and StaticSource

A SharedPV is a single data value which may be accessed by multiple clients through a Server. It is “shared” in the sense that all clients are manipulating a single variable.

#include <pvxs/sharedpv.h>
namespace pvxs { namespace server { ... } }

Each SharedPV instance has (after open() ) an associated data structure which is later manipulated with post().

A simple usage is:

using namespace pvxs;

auto initial = nt::NTScalar{TypeCode::Float64}.create();
initial["value"] = 42.0;

auto src(server::StaticSource::build());

auto pv(server::SharedPV::buildMailbox());
pv.open(initial);

src.add(argv[1], pv);

auto serv = server::Server::Config::fromEnv()
        .build()
        .addSource("box", src.source());

serv.run();

In this context “mailbox” refers to the default onPut() handler, which simply post()s whatever the client sends.

An example of a SharedPV with a custom Put handler

auto pv(server::SharedPV::buildMailbox());

pv.opPut([](server::SharedPV& pv,
            std::unique_ptr<server::ExecOp>&& op,
            Value&& top)
{
    // We decide that .value will be present with .open()
    auto val = top["value"];
    // is client trying to change .value ?
    if(val.isMarked(true, true)) {
        auto val = top["value"].as<double>();

        // clip to range [0, 10]
        top["value"] = std::max(0.0, std::min(val, 10.0));
    }

    // update and send to subscribers
    pv.post(std::move(top));
    // notify client of success  (or call op->error() if not)
    op->reply();
});

auto initial = nt::NTScalar{TypeCode::Float64}.create();
initial["value"] = 42.0;

auto src(server::StaticSource::build());

pv.open(initial);

Note

SharedPV follows the Source rules for Threading and locking.

struct pvxs::server::SharedPV

A SharedPV is a single data value which may be accessed by multiple clients through a Server.

On creation a SharedPV has no associated data structure, or data type. This is set by calling open() to provide a data type, and initial data values. Subsequent calls to post() will update this data structure (and send notifications to subscribing clients).

A later call to close() will force disconnect all clients, and discard the data value and type. A further call to open() sets a new data value, which may be of a different data type.

The onPut() and onRPC() methods attach functors which will be called each time a Put or RPC operation is executed by a client.

Public Functions

void attach(std::unique_ptr<ChannelControl> &&op)

Attach this SharedPV with a new client channel. Not necessary when using StaticSource. eg. could call from Source::onCreate()

void onFirstConnect(std::function<void(SharedPV&)> &&fn)

Callback when the number of attach()d clients becomes non-zero.

void onLastDisconnect(std::function<void(SharedPV&)> &&fn)

Callback when the number of attach()d clients becomes zero.

void onPut(std::function<void(SharedPV&, std::unique_ptr<ExecOp>&&, Value&&)> &&fn)

Callback when a client executes a new Put operation.

void onRPC(std::function<void(SharedPV&, std::unique_ptr<ExecOp>&&, Value&&)> &&fn)

Callback when a client executes an RPC operation.

Note

RPC operations are allowed even when the SharedPV is not opened (isOpen()==false)

void open(const Value &initial)

Provide data type and initial value. Allows clients to begin connecting.

Pre

!isOpen()

Parameters
  • initial: Defines data type, and initial value

bool isOpen() const

Test whether open() has been called w/o matching close()

void close()

Reverse the effects of open() and force disconnect any remaining clients.

void post(const Value &val)

Update the internal data value, and dispatch subscription updates to any clients.

void fetch(Value &val) const

query the internal data value and update the provided Value.

Value fetch() const

Return a (shallow) copy of the internal data value.

Public Static Functions

SharedPV buildMailbox()

Create a new SharedPV with a Put handler which post() s any client provided Value.

SharedPV buildReadonly()

Create a new SharedPV with a Put handler which rejects any client provided Value.

struct pvxs::server::StaticSource

Allow clients to find (through a Server) SharedPV instances by name.

A single PV name may only be added once to a StaticSource. However, a single SharedPV may be added multiple times with different PV names.

Public Functions

std::shared_ptr<Source> source() const

Fetch the Source interface, which may be used with Server::addSource()

void close()

call SharedPV::close() on all PVs

StaticSource &add(const std::string &name, const SharedPV &pv)

Add a new name through which a SharedPV may be addressed.

StaticSource &remove(const std::string &name)

Remove a single name.