17 #define epicsExportSharedSymbols 25 namespace epics {
namespace pvaClient {
29 PvaClientRPC::weak_pointer pvaClientRPC;
30 PvaClient::weak_pointer pvaClient;
35 : pvaClientRPC(pvaClientRPC),
39 if(PvaClient::getDebug()) std::cout <<
"~RPCRequesterImpl" << std::endl;
44 if(!clientRPC)
return string(
"pvaClientRPC is null");
45 return clientRPC->getRequesterName();
50 if(!clientRPC)
return;
51 clientRPC->message(message,messageType);
56 ChannelRPC::shared_pointer
const & channelRPC)
59 if(!clientRPC)
return;
60 clientRPC->rpcConnect(status,channelRPC);
65 ChannelRPC::shared_pointer
const & channelRPC,
66 PVStructure::shared_pointer
const & pvResponse)
69 if(!clientRPC)
return;
70 clientRPC->requestDone(status,channelRPC,pvResponse);
76 Channel::shared_pointer
const & channel)
80 return create(pvaClient,channel,pvRequest);
84 Channel::shared_pointer
const & channel,
93 PvaClientRPC::PvaClientRPC(
95 Channel::shared_pointer
const & channel,
98 connectState(connectIdle),
101 pvRequest(pvRequest),
105 if(PvaClient::getDebug()) {
106 cout<<
"PvaClientRPC::PvaClientRPC()" 107 <<
" channelName " << channel->getChannelName()
112 PvaClientRPC::~PvaClientRPC()
114 if(PvaClient::getDebug()) {
115 string channelName(
"disconnected");
116 Channel::shared_pointer chan(channel.lock());
117 if(chan) channelName = chan->getChannelName();
118 cout<<
"PvaClientRPC::~PvaClientRPC" 119 <<
" channelName " << channelName
124 void PvaClientRPC::checkRPCState()
126 if(PvaClient::getDebug()) {
127 string channelName(
"disconnected");
128 Channel::shared_pointer chan(channel.lock());
129 if(chan) channelName = chan->getChannelName();
130 cout <<
"PvaClientRPC::checkRPCState" 131 <<
" channelName " << channelName
132 <<
" connectState " << connectState
135 if(connectState==connectIdle) connect();
138 string PvaClientRPC::getRequesterName()
141 if(!yyy)
return string(
"PvaClientRPC::getRequesterName() PvaClient isDestroyed");
142 return yyy->getRequesterName();
145 void PvaClientRPC::message(
string const & message,
MessageType messageType)
149 yyy->message(message, messageType);
152 void PvaClientRPC::rpcConnect(
154 ChannelRPC::shared_pointer
const & channelRPC)
156 Channel::shared_pointer chan(channel.lock());
157 if(PvaClient::getDebug()) {
158 string channelName(
"disconnected");
159 Channel::shared_pointer chan(channel.lock());
160 if(chan) channelName = chan->getChannelName();
161 cout <<
"PvaClientRPC::rpcConnect" 162 <<
" channelName " << channelName
163 <<
" status.isOK " << (status.
isOK() ?
"true" :
"false")
168 connectState = connected;
169 if(PvaClient::getDebug()) {
170 cout <<
"PvaClientRPC::rpcConnect calling waitForConnect.signal\n";
172 waitForConnect.signal();
176 void PvaClientRPC::requestDone(
178 ChannelRPC::shared_pointer
const & channelRPC,
179 PVStructure::shared_pointer
const & pvResponse)
185 if(PvaClient::getDebug()) {
186 string channelName(
"disconnected");
187 Channel::shared_pointer chan(channel.lock());
188 if(chan) channelName = chan->getChannelName();
189 cout <<
"PvaClientRPC::requestDone" 190 <<
" channelName " << channelName
193 if(rpcState!=rpcActive) {
194 string channelName(
"disconnected");
195 Channel::shared_pointer chan(channel.lock());
196 if(chan) channelName = chan->getChannelName();
197 string message =
"channel " 199 +
" PvaClientRPC::requestDone" 201 throw std::runtime_error(message);
203 if(req && (responseTimeout<=0.0)) {
206 rpcState = rpcComplete;
207 if(!req) this->pvResponse = pvResponse;
208 waitForDone.signal();
212 req->requestDone(status,shared_from_this(),pvResponse);
216 void PvaClientRPC::connect()
218 if(PvaClient::getDebug()) cout <<
"PvaClientRPC::connect\n";
220 Status status = waitConnect();
221 if(status.
isOK())
return;
222 Channel::shared_pointer chan(channel.lock());
223 string channelName(
"disconnected");
224 if(chan) channelName = chan->getChannelName();
225 string message = string(
"channel ")
227 +
" PvaClientRPC::connect " 232 void PvaClientRPC::issueConnect()
234 if(PvaClient::getDebug()) cout <<
"PvaClientRPC::issueConnect\n";
235 Channel::shared_pointer chan(channel.lock());
236 if(connectState!=connectIdle) {
237 string channelName(
"disconnected");
238 if(chan) channelName = chan->getChannelName();
239 string message = string(
"channel ")
241 +
" pvaClientRPC already connected ";
242 throw std::runtime_error(message);
245 connectState = connectActive;
246 channelRPC = chan->createChannelRPC(rpcRequester,pvRequest);
249 throw std::runtime_error(
"PvaClientRPC::issueConnect() but channel disconnected");
254 if(PvaClient::getDebug()) cout <<
"PvaClientRPC::waitConnect\n";
255 if(connectState==connected) {
256 if(!connectStatus.isOK()) connectState = connectIdle;
257 return connectStatus;
259 if(connectState!=connectActive) {
260 Channel::shared_pointer chan(channel.lock());
261 string channelName(
"disconnected");
262 if(chan) channelName = chan->getChannelName();
263 string message = string(
"channel ")
265 +
" PvaClientRPC::waitConnect illegal connect state ";
266 throw std::runtime_error(message);
268 if(PvaClient::getDebug()) {
269 cout <<
"PvaClientRPC::waitConnect calling waitForConnect.wait\n";
271 waitForConnect.wait();
272 connectState = connectStatus.isOK() ? connected : connectIdle;
273 if(PvaClient::getDebug()) {
274 cout <<
"PvaClientRPC::waitConnect" 275 <<
" connectStatus " << (connectStatus.isOK() ?
"connected" :
"not connected");
277 return connectStatus;
285 if(rpcState!=rpcIdle) {
286 Channel::shared_pointer chan(channel.lock());
287 string channelName(
"disconnected");
288 if(chan) channelName = chan->getChannelName();
289 string message =
"channel " 291 +
" PvaClientRPC::request request aleady active ";
292 throw std::runtime_error(message);
294 rpcState = rpcActive;
296 channelRPC->request(pvArgument);
297 if(responseTimeout>0.0) {
298 waitForDone.wait(responseTimeout);
303 if(rpcState!=rpcComplete) {
304 Channel::shared_pointer chan(channel.lock());
305 string channelName(
"disconnected");
306 if(chan) channelName = chan->getChannelName();
307 string message =
"channel " 309 +
" PvaClientRPC::request request timeout ";
313 if(requestStatus.isOK())
return pvResponse;
314 Channel::shared_pointer chan(channel.lock());
315 string channelName(
"disconnected");
316 if(chan) channelName = chan->getChannelName();
317 string message =
"channel " 319 +
" PvaClientRPC::request status ";
320 message += requestStatus.getMessage();
326 PVStructure::shared_pointer
const & pvArgument,
330 this->pvaClientRPCRequester = pvaClientRPCRequester;
331 if(responseTimeout<=0.0) {
334 if(rpcState!=rpcIdle) {
335 Channel::shared_pointer chan(channel.lock());
336 string channelName(
"disconnected");
337 if(chan) channelName = chan->getChannelName();
338 string message =
"channel " 340 +
" PvaClientRPC::request request aleady active ";
341 throw std::runtime_error(message);
343 rpcState = rpcActive;
345 channelRPC->request(pvArgument);
std::tr1::shared_ptr< PvaClient > PvaClientPtr
virtual void message(std::string const &message, epics::pvData::MessageType messageType)
TODO only here because of the Lockable.
std::tr1::shared_ptr< const Structure > StructureConstPtr
A lock for multithreading.
An easy to use alternative to RPC.
const std::string & getMessage() const
virtual void requestDone(const Status &status, ChannelRPC::shared_pointer const &channelRPC, PVStructure::shared_pointer const &pvResponse)
virtual std::string getRequesterName()
FORCE_INLINE const FieldCreatePtr & getFieldCreate()
std::tr1::shared_ptr< PVStructure > PVStructurePtr
std::tr1::shared_ptr< RPCRequesterImpl > RPCRequesterImplPtr
virtual void channelRPCConnect(const epics::pvData::Status &status, ChannelRPC::shared_pointer const &channelRPC)
std::tr1::shared_ptr< PvaClientRPC > PvaClientRPCPtr
virtual ~RPCRequesterImpl()
std::tr1::shared_ptr< PvaClientRPCRequester > PvaClientRPCRequesterPtr
RPCRequesterImpl(PvaClientRPCPtr const &pvaClientRPC, PvaClientPtr const &pvaClient)
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()