pvxslibs 1.5.0__cp310-cp310-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pvxslibs/__init__.py +0 -0
- pvxslibs/dbd/pvxsIoc.dbd +8 -0
- pvxslibs/include/pvxs/client.h +1094 -0
- pvxslibs/include/pvxs/data.h +948 -0
- pvxslibs/include/pvxs/iochooks.h +170 -0
- pvxslibs/include/pvxs/log.h +148 -0
- pvxslibs/include/pvxs/netcommon.h +82 -0
- pvxslibs/include/pvxs/nt.h +208 -0
- pvxslibs/include/pvxs/server.h +238 -0
- pvxslibs/include/pvxs/sharedArray.h +748 -0
- pvxslibs/include/pvxs/sharedpv.h +121 -0
- pvxslibs/include/pvxs/source.h +290 -0
- pvxslibs/include/pvxs/srvcommon.h +148 -0
- pvxslibs/include/pvxs/unittest.h +327 -0
- pvxslibs/include/pvxs/util.h +354 -0
- pvxslibs/include/pvxs/version.h +97 -0
- pvxslibs/include/pvxs/versionNum.h +6 -0
- pvxslibs/ioc.py +10 -0
- pvxslibs/lib/__init__.py +0 -0
- pvxslibs/lib/event_core_dsoinfo.py +14 -0
- pvxslibs/lib/event_pthread_dsoinfo.py +14 -0
- pvxslibs/lib/libevent_core.so +0 -0
- pvxslibs/lib/libevent_core.so.2.2.0 +0 -0
- pvxslibs/lib/libevent_pthread.so +0 -0
- pvxslibs/lib/libevent_pthread.so.2.2.0 +0 -0
- pvxslibs/lib/libpvxs.so +0 -0
- pvxslibs/lib/libpvxs.so.1.5 +0 -0
- pvxslibs/lib/libpvxsIoc.so +0 -0
- pvxslibs/lib/libpvxsIoc.so.1.5 +0 -0
- pvxslibs/lib/pvxsIoc_dsoinfo.py +14 -0
- pvxslibs/lib/pvxs_dsoinfo.py +14 -0
- pvxslibs/path.py +12 -0
- pvxslibs/test/__init__.py +0 -0
- pvxslibs/test/test_load.py +30 -0
- pvxslibs/version.py +32 -0
- pvxslibs-1.5.0.dist-info/METADATA +44 -0
- pvxslibs-1.5.0.dist-info/RECORD +40 -0
- pvxslibs-1.5.0.dist-info/WHEEL +5 -0
- pvxslibs-1.5.0.dist-info/licenses/LICENSE +26 -0
- pvxslibs-1.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
3
|
+
* pvxs is distributed subject to a Software License Agreement found
|
|
4
|
+
* in file LICENSE that is included with this distribution.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#ifndef PVXS_SHAREDPV_H
|
|
8
|
+
#define PVXS_SHAREDPV_H
|
|
9
|
+
|
|
10
|
+
#include <functional>
|
|
11
|
+
#include <memory>
|
|
12
|
+
#include <map>
|
|
13
|
+
|
|
14
|
+
#include <pvxs/version.h>
|
|
15
|
+
#include "srvcommon.h"
|
|
16
|
+
|
|
17
|
+
namespace pvxs {
|
|
18
|
+
class Value;
|
|
19
|
+
|
|
20
|
+
namespace server {
|
|
21
|
+
|
|
22
|
+
struct ChannelControl;
|
|
23
|
+
struct Source;
|
|
24
|
+
|
|
25
|
+
/** A SharedPV is a single data value which may be accessed by multiple clients through a Server.
|
|
26
|
+
*
|
|
27
|
+
* On creation a SharedPV has no associated data structure, or data type.
|
|
28
|
+
* This is set by calling open() to provide a data type, and initial data values.
|
|
29
|
+
* Subsequent calls to post() will update this data structure (and send notifications
|
|
30
|
+
* to subscribing clients).
|
|
31
|
+
*
|
|
32
|
+
* A later call to close() will force disconnect all clients, and discard the data value and type.
|
|
33
|
+
* A further call to open() sets a new data value, which may be of a different data type.
|
|
34
|
+
*
|
|
35
|
+
* The onPut() and onRPC() methods attach functors which will be called each time a Put or RPC
|
|
36
|
+
* operation is executed by a client.
|
|
37
|
+
*/
|
|
38
|
+
struct PVXS_API SharedPV
|
|
39
|
+
{
|
|
40
|
+
//! Create a new SharedPV with a Put handler which post() s any client provided Value.
|
|
41
|
+
static SharedPV buildMailbox();
|
|
42
|
+
//! Create a new SharedPV with a Put handler which rejects any client provided Value.
|
|
43
|
+
static SharedPV buildReadonly();
|
|
44
|
+
|
|
45
|
+
~SharedPV();
|
|
46
|
+
|
|
47
|
+
inline explicit operator bool() const { return !!impl; }
|
|
48
|
+
|
|
49
|
+
//! Attach this SharedPV with a new client channel.
|
|
50
|
+
//! Not necessary when using StaticSource.
|
|
51
|
+
//! eg. could call from Source::onCreate()
|
|
52
|
+
void attach(std::unique_ptr<ChannelControl>&& op);
|
|
53
|
+
|
|
54
|
+
//! Callback when the number of attach()d clients becomes non-zero.
|
|
55
|
+
void onFirstConnect(std::function<void(SharedPV&)>&& fn);
|
|
56
|
+
//! Callback when the number of attach()d clients becomes zero.
|
|
57
|
+
void onLastDisconnect(std::function<void(SharedPV&)>&& fn);
|
|
58
|
+
//! Callback when a client executes a new Put operation.
|
|
59
|
+
void onPut(std::function<void(SharedPV&, std::unique_ptr<ExecOp>&&, Value&&)>&& fn);
|
|
60
|
+
//! Callback when a client executes an RPC operation.
|
|
61
|
+
//! @note RPC operations are allowed even when the SharedPV is not opened (isOpen()==false)
|
|
62
|
+
void onRPC(std::function<void(SharedPV&, std::unique_ptr<ExecOp>&&, Value&&)>&& fn);
|
|
63
|
+
|
|
64
|
+
/** Provide data type and initial value. Allows clients to begin connecting.
|
|
65
|
+
* @pre !isOpen()
|
|
66
|
+
* @param initial Defines data type, and initial value
|
|
67
|
+
*/
|
|
68
|
+
void open(const Value& initial);
|
|
69
|
+
//! Test whether open() has been called w/o matching close()
|
|
70
|
+
bool isOpen() const;
|
|
71
|
+
//! Reverse the effects of open() and force disconnect any remaining clients.
|
|
72
|
+
void close();
|
|
73
|
+
|
|
74
|
+
//! Update the internal data value, and dispatch subscription updates to any clients.
|
|
75
|
+
void post(const Value& val);
|
|
76
|
+
//! query the internal data value and update the provided Value.
|
|
77
|
+
void fetch(Value& val) const;
|
|
78
|
+
//! Return a (shallow) copy of the internal data value
|
|
79
|
+
Value fetch() const;
|
|
80
|
+
|
|
81
|
+
struct Impl;
|
|
82
|
+
private:
|
|
83
|
+
std::shared_ptr<Impl> impl;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/** Allow clients to find (through a Server) SharedPV instances by name.
|
|
87
|
+
*
|
|
88
|
+
* A single PV name may only be added once to a StaticSource.
|
|
89
|
+
* However, a single SharedPV may be added multiple times with different PV names.
|
|
90
|
+
*/
|
|
91
|
+
struct PVXS_API StaticSource
|
|
92
|
+
{
|
|
93
|
+
static StaticSource build();
|
|
94
|
+
|
|
95
|
+
~StaticSource();
|
|
96
|
+
|
|
97
|
+
inline explicit operator bool() const { return !!impl; }
|
|
98
|
+
|
|
99
|
+
//! Fetch the Source interface, which may be used with Server::addSource()
|
|
100
|
+
std::shared_ptr<Source> source() const;
|
|
101
|
+
|
|
102
|
+
//! call SharedPV::close() on all PVs
|
|
103
|
+
void close();
|
|
104
|
+
|
|
105
|
+
//! Add a new name through which a SharedPV may be addressed.
|
|
106
|
+
StaticSource& add(const std::string& name, const SharedPV& pv);
|
|
107
|
+
//! Remove a single name
|
|
108
|
+
StaticSource& remove(const std::string& name);
|
|
109
|
+
|
|
110
|
+
typedef std::map<std::string, SharedPV> list_t;
|
|
111
|
+
list_t list() const;
|
|
112
|
+
|
|
113
|
+
struct Impl;
|
|
114
|
+
private:
|
|
115
|
+
std::shared_ptr<Impl> impl;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
} // namespace server
|
|
119
|
+
} // namespace pvxs
|
|
120
|
+
|
|
121
|
+
#endif // PVXS_SHAREDPV_H
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
3
|
+
* pvxs is distributed subject to a Software License Agreement found
|
|
4
|
+
* in file LICENSE that is included with this distribution.
|
|
5
|
+
*/
|
|
6
|
+
#ifndef PVXS_SOURCE_H
|
|
7
|
+
#define PVXS_SOURCE_H
|
|
8
|
+
|
|
9
|
+
#include <string>
|
|
10
|
+
#include <functional>
|
|
11
|
+
|
|
12
|
+
#include <pvxs/data.h>
|
|
13
|
+
#include <pvxs/server.h>
|
|
14
|
+
#include "srvcommon.h"
|
|
15
|
+
|
|
16
|
+
namespace pvxs {
|
|
17
|
+
namespace impl {
|
|
18
|
+
struct ServerConn;
|
|
19
|
+
}
|
|
20
|
+
namespace server {
|
|
21
|
+
|
|
22
|
+
//! Handle when an operation is being setup
|
|
23
|
+
struct PVXS_API ConnectOp : public OpBase, public RemoteLogger {
|
|
24
|
+
protected:
|
|
25
|
+
Value _pvRequest;
|
|
26
|
+
public:
|
|
27
|
+
const Value& pvRequest() const { return _pvRequest; }
|
|
28
|
+
|
|
29
|
+
//! For GET_FIELD, GET, or PUT. Inform peer of our data-type.
|
|
30
|
+
//! @throws std::runtime_error if the client pvRequest() field mask does not select any fields of prototype.
|
|
31
|
+
virtual void connect(const Value& prototype) =0;
|
|
32
|
+
//! Indicate that this operation can not be setup
|
|
33
|
+
//! @since 1.2.3 Does not block
|
|
34
|
+
virtual void error(const std::string& msg) =0;
|
|
35
|
+
|
|
36
|
+
ConnectOp(const std::string& name,
|
|
37
|
+
const std::shared_ptr<const ClientCredentials>& cred, op_t op,
|
|
38
|
+
const Value& pvRequest)
|
|
39
|
+
:OpBase(name, cred, op)
|
|
40
|
+
,_pvRequest(pvRequest)
|
|
41
|
+
{}
|
|
42
|
+
virtual ~ConnectOp();
|
|
43
|
+
|
|
44
|
+
//! Handler invoked when a peer executes a request for data on a GET o PUT
|
|
45
|
+
virtual void onGet(std::function<void(std::unique_ptr<ExecOp>&&)>&& fn) =0;
|
|
46
|
+
//! Handler invoked when a peer executes a send data on a PUT
|
|
47
|
+
virtual void onPut(std::function<void(std::unique_ptr<ExecOp>&&, Value&&)>&& fn) =0;
|
|
48
|
+
//! Callback when the underlying channel closes
|
|
49
|
+
virtual void onClose(std::function<void(const std::string&)>&&) =0;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//! Information about a running monitor
|
|
53
|
+
struct MonitorStat {
|
|
54
|
+
//! Number of available elements in the output flow window.
|
|
55
|
+
size_t window=0;
|
|
56
|
+
|
|
57
|
+
//! Number of un-sent updates in the local queue. Doesn't include updates
|
|
58
|
+
//! serialized and in the TX buffer.
|
|
59
|
+
size_t nQueue=0;
|
|
60
|
+
//! Highest value of nQueue seen
|
|
61
|
+
//! @since 1.1.0
|
|
62
|
+
size_t maxQueue=0;
|
|
63
|
+
//! Negotiated limit on nQueue
|
|
64
|
+
size_t limitQueue=0;
|
|
65
|
+
//! Number of updates squashed during post() calls
|
|
66
|
+
//! @since 1.2.0
|
|
67
|
+
size_t nSquash=0;
|
|
68
|
+
|
|
69
|
+
bool running=false;
|
|
70
|
+
bool finished=false;
|
|
71
|
+
bool pipeline=false;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
//! Handle for active subscription
|
|
75
|
+
struct PVXS_API MonitorControlOp : public OpBase, public RemoteLogger {
|
|
76
|
+
MonitorControlOp(const std::string& name,
|
|
77
|
+
const std::shared_ptr<const ClientCredentials>& cred, op_t op)
|
|
78
|
+
:OpBase(name, cred, op)
|
|
79
|
+
{}
|
|
80
|
+
virtual ~MonitorControlOp();
|
|
81
|
+
|
|
82
|
+
protected:
|
|
83
|
+
virtual bool doPost(const Value& val, bool maybe, bool force) =0;
|
|
84
|
+
public:
|
|
85
|
+
|
|
86
|
+
//! Add a new entry to the monitor queue.
|
|
87
|
+
//! If nFree()<=0 the output queue will be over-filled with this element.
|
|
88
|
+
//! Returns @code nFree()>0u @endcode
|
|
89
|
+
//! @warning Caller must not modify the Value
|
|
90
|
+
bool forcePost(const Value& val) {
|
|
91
|
+
return doPost(val, false, true);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
//! Add a new entry to the monitor queue.
|
|
95
|
+
//! If nFree()<=0 this element will be "squashed" to the last element in the queue
|
|
96
|
+
//! Returns @code nFree()>0u @endcode
|
|
97
|
+
//! @warning Caller must not modify the Value
|
|
98
|
+
bool post(const Value& val) {
|
|
99
|
+
return doPost(val, false, false);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
//! Add a new entry to the monitor queue.
|
|
103
|
+
//! If nFree()<=0 return false and take no other action
|
|
104
|
+
//! Returns @code nFree()>0u @endcode
|
|
105
|
+
//! @warning Caller must not modify the Value
|
|
106
|
+
bool tryPost(const Value& val) {
|
|
107
|
+
return doPost(val, true, false);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//! Signal to subscriber that this subscription will not yield any further events.
|
|
111
|
+
//! This is not an error. Client should not retry.
|
|
112
|
+
void finish() {
|
|
113
|
+
doPost(Value(), false, true);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//! Poll information and statistics for this subscription.
|
|
117
|
+
//! @since 1.1.0 Added 'reset' argument.
|
|
118
|
+
virtual void stats(MonitorStat&, bool reset=false) const =0;
|
|
119
|
+
|
|
120
|
+
/** Set flow control levels.
|
|
121
|
+
*
|
|
122
|
+
* Flow control operations against an outbound "window" size, which is the number of updates which may
|
|
123
|
+
* be sent before a client ack. must be received. By default both high and low levels are zero.
|
|
124
|
+
*
|
|
125
|
+
* onLowMark callback is not currently implemented and the 'low' level is not used.
|
|
126
|
+
* onHighMark callback will be invoked when a client ack. is received and the window size is above (>) 'high'.
|
|
127
|
+
*/
|
|
128
|
+
virtual void setWatermarks(size_t low, size_t high) =0;
|
|
129
|
+
|
|
130
|
+
//! Callback when client resumes/pauses updates
|
|
131
|
+
virtual void onStart(std::function<void(bool start)>&&) =0;
|
|
132
|
+
virtual void onHighMark(std::function<void()>&&) =0;
|
|
133
|
+
virtual void onLowMark(std::function<void()>&&) =0;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
//! Handle for subscription which is being setup
|
|
137
|
+
struct PVXS_API MonitorSetupOp : public OpBase, public RemoteLogger {
|
|
138
|
+
protected:
|
|
139
|
+
Value _pvRequest;
|
|
140
|
+
public:
|
|
141
|
+
const Value& pvRequest() const { return _pvRequest; }
|
|
142
|
+
|
|
143
|
+
//! Inform peer of our data-type and acquire control of subscription queue.
|
|
144
|
+
//! The queue is initially stopped.
|
|
145
|
+
//! @throws std::runtime_error if the client pvRequest() field mask does not select any fields of prototype.
|
|
146
|
+
virtual std::unique_ptr<MonitorControlOp> connect(const Value& prototype) =0;
|
|
147
|
+
|
|
148
|
+
//! Indicate that this operation can not be setup
|
|
149
|
+
//! @since 1.2.3 Does not block
|
|
150
|
+
virtual void error(const std::string& msg) =0;
|
|
151
|
+
|
|
152
|
+
MonitorSetupOp(const std::string& name,
|
|
153
|
+
const std::shared_ptr<const ClientCredentials>& cred, op_t op,
|
|
154
|
+
const Value& pvRequest)
|
|
155
|
+
:OpBase(name, cred, op)
|
|
156
|
+
,_pvRequest(pvRequest)
|
|
157
|
+
{}
|
|
158
|
+
virtual ~MonitorSetupOp();
|
|
159
|
+
|
|
160
|
+
virtual void onClose(std::function<void(const std::string&)>&&) =0;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/** Manipulate an active Channel, and any in-progress Operations through it.
|
|
164
|
+
*
|
|
165
|
+
*/
|
|
166
|
+
struct PVXS_API ChannelControl : public OpBase {
|
|
167
|
+
ChannelControl(const std::string& name,
|
|
168
|
+
const std::shared_ptr<const ClientCredentials>& cred, op_t op)
|
|
169
|
+
:OpBase(name, cred, op)
|
|
170
|
+
{}
|
|
171
|
+
virtual ~ChannelControl() =0;
|
|
172
|
+
|
|
173
|
+
//! Invoked when a new GET or PUT Operation is requested through this Channel
|
|
174
|
+
virtual void onOp(std::function<void(std::unique_ptr<ConnectOp>&&)>&& ) =0;
|
|
175
|
+
//! Invoked when the peer executes an RPC
|
|
176
|
+
virtual void onRPC(std::function<void(std::unique_ptr<ExecOp>&&, Value&&)>&& fn)=0;
|
|
177
|
+
//! Invoked when the peer create a new subscription
|
|
178
|
+
virtual void onSubscribe(std::function<void(std::unique_ptr<MonitorSetupOp>&&)>&&)=0;
|
|
179
|
+
|
|
180
|
+
//! Callback when the channel closes (eg. peer disconnect)
|
|
181
|
+
virtual void onClose(std::function<void(const std::string&)>&&) =0;
|
|
182
|
+
|
|
183
|
+
//! Force disconnection
|
|
184
|
+
//! If called from outside a handler method, blocks until in-progress Handler methods have returned.
|
|
185
|
+
//! Reference to currently attached Handler is released.
|
|
186
|
+
virtual void close() =0;
|
|
187
|
+
|
|
188
|
+
// TODO: signal Rights?
|
|
189
|
+
|
|
190
|
+
#ifdef PVXS_EXPERT_API_ENABLED
|
|
191
|
+
// Store info struct which will be returned with Report::Channel
|
|
192
|
+
inline void updateInfo(const std::shared_ptr<const ReportInfo>& info)
|
|
193
|
+
{ this->_updateInfo(info); }
|
|
194
|
+
#endif
|
|
195
|
+
private:
|
|
196
|
+
virtual void _updateInfo(const std::shared_ptr<const ReportInfo>& info) =0;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/** Interface through which a Server discovers Channel names and
|
|
200
|
+
* associates with Handler instances.
|
|
201
|
+
*
|
|
202
|
+
* User code will sub-class.
|
|
203
|
+
*/
|
|
204
|
+
struct PVXS_API Source {
|
|
205
|
+
virtual ~Source() =0;
|
|
206
|
+
|
|
207
|
+
/** An iterable of names (Name) being sought.
|
|
208
|
+
*
|
|
209
|
+
* @code
|
|
210
|
+
* virtual void onSearch(Search& search) {
|
|
211
|
+
* for(auto& op : search) {
|
|
212
|
+
* if(strcmp(op.name(), "magic")==0)
|
|
213
|
+
* op.claim();
|
|
214
|
+
* }
|
|
215
|
+
* }
|
|
216
|
+
* @endcode
|
|
217
|
+
*/
|
|
218
|
+
struct Search {
|
|
219
|
+
//! A single name being searched
|
|
220
|
+
class Name {
|
|
221
|
+
const char* _name = nullptr;
|
|
222
|
+
bool _claim = false;
|
|
223
|
+
friend struct Server::Pvt;
|
|
224
|
+
friend struct impl::ServerConn;
|
|
225
|
+
public:
|
|
226
|
+
//! The Channel name
|
|
227
|
+
inline const char* name() const { return _name; }
|
|
228
|
+
//! The caller claims to be able to respond to an onCreate() for this name.
|
|
229
|
+
inline void claim() { _claim = true; }
|
|
230
|
+
// TODO claim w/ redirect
|
|
231
|
+
};
|
|
232
|
+
private:
|
|
233
|
+
typedef std::vector<Name> _names_t;
|
|
234
|
+
_names_t _names;
|
|
235
|
+
char _src[80]; // >= INET6_ADDRSTRLEN+1
|
|
236
|
+
friend struct Server::Pvt;
|
|
237
|
+
friend struct impl::ServerConn;
|
|
238
|
+
public:
|
|
239
|
+
typedef Name value_type;
|
|
240
|
+
typedef _names_t::iterator iterator;
|
|
241
|
+
|
|
242
|
+
//! Number of names
|
|
243
|
+
inline size_t size() const { return _names.size(); }
|
|
244
|
+
//! Begin iterator of Name instances
|
|
245
|
+
iterator begin() { return _names.begin(); }
|
|
246
|
+
//! End iterator of Name instances
|
|
247
|
+
iterator end() { return _names.end(); }
|
|
248
|
+
//! The Client endpoint address
|
|
249
|
+
const char* source() const { return _src; }
|
|
250
|
+
};
|
|
251
|
+
/** Called each time a client polls for the existence of some Channel names (Search::Name).
|
|
252
|
+
*
|
|
253
|
+
* A Source may only Search::Name::claim() a Channel name if it is prepared to
|
|
254
|
+
* immediately accept an onCreate() call for that Channel name.
|
|
255
|
+
* In other situations it should wait for the client to retry.
|
|
256
|
+
*/
|
|
257
|
+
virtual void onSearch(Search& op) =0;
|
|
258
|
+
|
|
259
|
+
/** A Client is attempting to open a connection to a certain Channel.
|
|
260
|
+
*
|
|
261
|
+
* This Channel name may not be one which was seen or claimed by onSearch().
|
|
262
|
+
*
|
|
263
|
+
* Callee may:
|
|
264
|
+
*
|
|
265
|
+
* - Do nothing, allowing some other Source with higher/later order a chance to create.
|
|
266
|
+
* - Call ChannelControl::close() to explicitly reject the channel.
|
|
267
|
+
* - std::move() the op and/or call ChannelControl::setHandler() to accept the new channel.
|
|
268
|
+
* - std::move() the op and allow ChannelControl to be destroyed to implicitly reject the channel.
|
|
269
|
+
*/
|
|
270
|
+
virtual void onCreate(std::unique_ptr<ChannelControl>&& op) =0;
|
|
271
|
+
|
|
272
|
+
//! List of channel names
|
|
273
|
+
struct List {
|
|
274
|
+
//! The list
|
|
275
|
+
std::shared_ptr<const std::set<std::string>> names;
|
|
276
|
+
//! True if the list may change at some future time.
|
|
277
|
+
bool dynamic;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
/** A Client is requesting a list of Channel names which we may claim.
|
|
281
|
+
*/
|
|
282
|
+
virtual List onList();
|
|
283
|
+
|
|
284
|
+
//! Print status information.
|
|
285
|
+
virtual void show(std::ostream& strm);
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
}} // namespace pvxs::server
|
|
289
|
+
|
|
290
|
+
#endif // PVXS_SOURCE_H
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
3
|
+
* pvxs is distributed subject to a Software License Agreement found
|
|
4
|
+
* in file LICENSE that is included with this distribution.
|
|
5
|
+
*/
|
|
6
|
+
#ifndef PVXS_SRVCOMMON_H
|
|
7
|
+
#define PVXS_SRVCOMMON_H
|
|
8
|
+
|
|
9
|
+
#if !defined(PVXS_SHAREDPV_H) && !defined(PVXS_SOURCE_H)
|
|
10
|
+
# error Include <pvxs/sharedpv.h> or <pvxs/source.h> Do not include srvcommon.h directly
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#include <iosfwd>
|
|
14
|
+
#include <string>
|
|
15
|
+
#include <set>
|
|
16
|
+
#include <functional>
|
|
17
|
+
|
|
18
|
+
#include <pvxs/version.h>
|
|
19
|
+
#include <pvxs/util.h>
|
|
20
|
+
#include <pvxs/data.h>
|
|
21
|
+
|
|
22
|
+
namespace pvxs {
|
|
23
|
+
enum struct Level;
|
|
24
|
+
namespace server {
|
|
25
|
+
|
|
26
|
+
/** Credentials presented by a client.
|
|
27
|
+
*
|
|
28
|
+
* Primarily a way of presenting peer address and a remote user account name.
|
|
29
|
+
* The method gives the authentication sub-protocol used and is presently one of:
|
|
30
|
+
*
|
|
31
|
+
* - "ca" - Client provided account name.
|
|
32
|
+
* - "anonymous" - Client provided no credentials. account will also be "anonymous".
|
|
33
|
+
*
|
|
34
|
+
* @since 0.2.0
|
|
35
|
+
*/
|
|
36
|
+
struct PVXS_API ClientCredentials {
|
|
37
|
+
//! Peer address (eg. numeric IPv4)
|
|
38
|
+
std::string peer;
|
|
39
|
+
//! The local interface address (eg. numeric IPv4) through which this client is connected.
|
|
40
|
+
//! May be a wildcard address (eg. 0.0.0.0) if the receiving socket is so bound.
|
|
41
|
+
std::string iface;
|
|
42
|
+
//! Authentication "method"
|
|
43
|
+
std::string method;
|
|
44
|
+
//! Remote user account name. Meaning depends upon method.
|
|
45
|
+
std::string account;
|
|
46
|
+
//! (Copy of) Credentials blob as presented by the client.
|
|
47
|
+
Value raw;
|
|
48
|
+
/** Lookup (locally) roles associated with the account.
|
|
49
|
+
*
|
|
50
|
+
* On *nix targets this is the list of primary and secondary groups
|
|
51
|
+
* in with the account is a member.
|
|
52
|
+
* On Windows targets this returns the list of local groups for the account.
|
|
53
|
+
* On other targets, an empty list is returned.
|
|
54
|
+
*/
|
|
55
|
+
std::set<std::string> roles() const;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
PVXS_API
|
|
59
|
+
std::ostream& operator<<(std::ostream&, const ClientCredentials&);
|
|
60
|
+
|
|
61
|
+
//! Base for all operation classes
|
|
62
|
+
struct PVXS_API OpBase {
|
|
63
|
+
enum op_t {
|
|
64
|
+
None, //!< invalid
|
|
65
|
+
Info, //!< A GET_FIELD operation
|
|
66
|
+
Get, //!< A GET operation
|
|
67
|
+
Put, //!< A PUT operation
|
|
68
|
+
RPC, //!< A RPC operation
|
|
69
|
+
};
|
|
70
|
+
protected:
|
|
71
|
+
const std::string _name;
|
|
72
|
+
const std::shared_ptr<const ClientCredentials> _cred;
|
|
73
|
+
const op_t _op;
|
|
74
|
+
public:
|
|
75
|
+
//! The Client endpoint address in "X.X.X.X:Y" format.
|
|
76
|
+
const std::string& peerName() const { return _cred->peer; }
|
|
77
|
+
//! The Channel name
|
|
78
|
+
const std::string& name() const { return _name; }
|
|
79
|
+
//! Client credentials. Never NULL.
|
|
80
|
+
//! @since 0.2.0
|
|
81
|
+
const std::shared_ptr<const ClientCredentials>& credentials() const { return _cred; }
|
|
82
|
+
//! Operation type
|
|
83
|
+
op_t op() const { return _op; }
|
|
84
|
+
|
|
85
|
+
OpBase(const std::string& name,
|
|
86
|
+
const std::shared_ptr<const ClientCredentials>& cred, op_t op)
|
|
87
|
+
:_name(name)
|
|
88
|
+
,_cred(cred)
|
|
89
|
+
,_op(op)
|
|
90
|
+
{}
|
|
91
|
+
OpBase(const OpBase&) = delete;
|
|
92
|
+
OpBase& operator=(const OpBase&) = delete;
|
|
93
|
+
virtual ~OpBase() =0;
|
|
94
|
+
};
|
|
95
|
+
//! Log to remote peer
|
|
96
|
+
//! @since 1.4.0
|
|
97
|
+
struct PVXS_API RemoteLogger {
|
|
98
|
+
virtual ~RemoteLogger() =0;
|
|
99
|
+
|
|
100
|
+
//! Request log message to peer
|
|
101
|
+
//! @since 1.4.0
|
|
102
|
+
virtual void logRemote(Level lvl, const std::string& msg) =0;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
//! Handle when an operation is being executed
|
|
106
|
+
struct PVXS_API ExecOp : public OpBase, public RemoteLogger {
|
|
107
|
+
//! Issue a reply without data. (eg. to complete a PUT)
|
|
108
|
+
virtual void reply() =0;
|
|
109
|
+
//! Issue a reply with data. For a GET or RPC (or PUT/Get)
|
|
110
|
+
virtual void reply(const Value& val) =0;
|
|
111
|
+
//! Indicate the request has resulted in an error.
|
|
112
|
+
//! @since 1.2.3 Does not block
|
|
113
|
+
virtual void error(const std::string& msg) =0;
|
|
114
|
+
|
|
115
|
+
//! Callback invoked if the peer cancels the operation before reply() or error() is called.
|
|
116
|
+
virtual void onCancel(std::function<void()>&&) =0;
|
|
117
|
+
|
|
118
|
+
protected:
|
|
119
|
+
const Value _pvRequest;
|
|
120
|
+
public:
|
|
121
|
+
//! Access to pvRequest blob
|
|
122
|
+
//! @since 0.2.0
|
|
123
|
+
const Value& pvRequest() const { return _pvRequest; }
|
|
124
|
+
|
|
125
|
+
ExecOp(const std::string& name,
|
|
126
|
+
const std::shared_ptr<const ClientCredentials>& cred, op_t op,
|
|
127
|
+
const Value& pvRequest)
|
|
128
|
+
:OpBase(name, cred, op)
|
|
129
|
+
,_pvRequest(pvRequest)
|
|
130
|
+
{}
|
|
131
|
+
ExecOp(const ExecOp&) = delete;
|
|
132
|
+
ExecOp& operator=(const ExecOp&) = delete;
|
|
133
|
+
virtual ~ExecOp();
|
|
134
|
+
|
|
135
|
+
#ifdef PVXS_EXPERT_API_ENABLED
|
|
136
|
+
//! Create/start timer. cb runs on worker associated with Channel of this Operation.
|
|
137
|
+
//! @since 0.2.0
|
|
138
|
+
Timer timerOneShot(double delay, std::function<void()>&& cb) {
|
|
139
|
+
return _timerOneShot(delay, std::move(cb));
|
|
140
|
+
}
|
|
141
|
+
#endif // PVXS_EXPERT_API_ENABLED
|
|
142
|
+
private:
|
|
143
|
+
virtual Timer _timerOneShot(double delay, std::function<void()>&& cb) =0;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
}} // namespace pvxs::server
|
|
147
|
+
|
|
148
|
+
#endif // PVXS_SRVCOMMON_H
|