pvDatabaseCPP  4.5.1
channelLocal.cpp
Go to the documentation of this file.
1 /* channelLocal.cpp */
12 #include <sstream>
13 
14 #include <epicsGuard.h>
15 #include <epicsThread.h>
16 #include <pv/pvData.h>
17 #include <pv/pvAccess.h>
18 #include <pv/pvTimeStamp.h>
19 #include <pv/rpcService.h>
20 #include <pv/timeStamp.h>
21 #include <pv/createRequest.h>
22 #include <pv/pvaVersion.h>
23 #include <pv/pvaVersionNum.h>
24 #include <pv/serverContext.h>
25 #include <pv/pvSubArrayCopy.h>
26 
27 #define epicsExportSharedSymbols
28 #include "pv/pvStructureCopy.h"
29 #include "pv/pvDatabase.h"
31 
32 using namespace epics::pvData;
33 using namespace epics::pvAccess;
34 using namespace epics::pvCopy;
35 using std::tr1::static_pointer_cast;
36 using std::tr1::dynamic_pointer_cast;
37 using std::cout;
38 using std::endl;
39 using std::string;
40 
41 namespace epics { namespace pvDatabase {
42 
43 static StructureConstPtr nullStructure;
44 
45 class ChannelProcessLocal;
46 typedef std::tr1::shared_ptr<ChannelProcessLocal> ChannelProcessLocalPtr;
47 class ChannelGetLocal;
48 typedef std::tr1::shared_ptr<ChannelGetLocal> ChannelGetLocalPtr;
49 class ChannelPutLocal;
50 typedef std::tr1::shared_ptr<ChannelPutLocal> ChannelPutLocalPtr;
51 class ChannelPutGetLocal;
52 typedef std::tr1::shared_ptr<ChannelPutGetLocal> ChannelPutGetLocalPtr;
53 class ChannelRPCLocal;
54 typedef std::tr1::shared_ptr<ChannelRPCLocal> ChannelRPCLocalPtr;
55 class ChannelArrayLocal;
56 typedef std::tr1::shared_ptr<ChannelArrayLocal> ChannelArrayLocalPtr;
57 
58 static bool getProcess(PVStructurePtr pvRequest,bool processDefault)
59 {
60  PVFieldPtr pvField = pvRequest->getSubField("record._options.process");
61  if(!pvField || pvField->getField()->getType()!=scalar) {
62  return processDefault;
63  }
64  ScalarConstPtr scalar = static_pointer_cast<const Scalar>(
65  pvField->getField());
66  if(scalar->getScalarType()==pvString) {
67  PVStringPtr pvString = static_pointer_cast<PVString>(pvField);
68  return pvString->get().compare("true")==0 ? true : false;
69  } else if(scalar->getScalarType()==pvBoolean) {
70  PVBooleanPtr pvBoolean = static_pointer_cast<PVBoolean>(pvField);
71  return pvBoolean->get();
72  }
73  return processDefault;
74 }
75 
76 class ChannelProcessLocal :
77  public ChannelProcess,
78  public std::tr1::enable_shared_from_this<ChannelProcessLocal>
79 {
80 public:
81  POINTER_DEFINITIONS(ChannelProcessLocal);
82  virtual ~ChannelProcessLocal();
83  virtual void destroy() {} // DEPRECATED
84  static ChannelProcessLocalPtr create(
85  ChannelLocalPtr const &channelLocal,
86  ChannelProcessRequester::shared_pointer const & channelProcessRequester,
87  PVStructurePtr const & pvRequest,
88  PVRecordPtr const &pvRecord);
89  virtual void process();
90  virtual std::tr1::shared_ptr<Channel> getChannel();
91  virtual void cancel(){}
92  virtual void lock();
93  virtual void unlock();
94  virtual void lastRequest() {}
95 private:
96  shared_pointer getPtrSelf()
97  {
98  return shared_from_this();
99  }
100  ChannelProcessLocal(
101  ChannelLocalPtr const &channelLocal,
102  ChannelProcessRequester::shared_pointer const & channelProcessRequester,
103  PVRecordPtr const &pvRecord,
104  int nProcess)
105  :
106  channelLocal(channelLocal),
107  channelProcessRequester(channelProcessRequester),
108  pvRecord(pvRecord),
109  nProcess(nProcess)
110  {
111  }
112  ChannelLocalWPtr channelLocal;
113  ChannelProcessRequester::weak_pointer channelProcessRequester;
114  PVRecordWPtr pvRecord;
115  int nProcess;
116  Mutex mutex;
117 };
118 
119 ChannelProcessLocalPtr ChannelProcessLocal::create(
120  ChannelLocalPtr const &channelLocal,
121  ChannelProcessRequester::shared_pointer const & channelProcessRequester,
122  PVStructurePtr const & pvRequest,
123  PVRecordPtr const &pvRecord)
124 {
125  PVFieldPtr pvField;
126  PVStructurePtr pvOptions;
127  int nProcess = 1;
128  if(pvRequest) pvField = pvRequest->getSubField("record._options");
129  if(pvField) {
130  pvOptions = static_pointer_cast<PVStructure>(pvField);
131  pvField = pvOptions->getSubField("nProcess");
132  if(pvField) {
133  PVStringPtr pvString = pvOptions->getSubField<PVString>("nProcess");
134  if(pvString) {
135  int size;
136  std::stringstream ss;
137  ss << pvString->get();
138  ss >> size;
139  nProcess = size;
140  }
141  }
142  }
143  ChannelProcessLocalPtr process(new ChannelProcessLocal(
144  channelLocal,
145  channelProcessRequester,
146  pvRecord,
147  nProcess));
148  if(pvRecord->getTraceLevel()>0)
149  {
150  cout << "ChannelProcessLocal::create";
151  cout << " recordName " << pvRecord->getRecordName() << endl;
152  }
153  channelProcessRequester->channelProcessConnect(Status::Ok, process);
154  return process;
155 }
156 
157 ChannelProcessLocal::~ChannelProcessLocal()
158 {
159  PVRecordPtr pvr(pvRecord.lock());
160  if(pvr && pvr->getTraceLevel()>0) {
161  cout << "~ChannelProcessLocal() " << pvr->getRecordName() << endl;
162  }
163 }
164 
165 std::tr1::shared_ptr<Channel> ChannelProcessLocal::getChannel()
166 {
167  ChannelLocalPtr channel(channelLocal.lock());
168  return channel;
169 }
170 
171 void ChannelProcessLocal::lock()
172 {
173  PVRecordPtr pvr(pvRecord.lock());
174  if(!pvr) throw std::logic_error("pvRecord is deleted");
175  pvr->lock();
176 }
177 void ChannelProcessLocal::unlock()
178 {
179  PVRecordPtr pvr(pvRecord.lock());
180  if(!pvr) throw std::logic_error("pvRecord is deleted");
181  pvr->unlock();
182 }
183 
184 void ChannelProcessLocal::process()
185 {
186  ChannelProcessRequester::shared_pointer requester = channelProcessRequester.lock();
187  if(!requester) return;
188  PVRecordPtr pvr(pvRecord.lock());
189  if(!pvr) throw std::logic_error("pvRecord is deleted");
190  if(pvr->getTraceLevel()>1)
191  {
192  cout << "ChannelProcessLocal::process";
193  cout << " nProcess " << nProcess << endl;
194  }
195  try {
196  for(int i=0; i< nProcess; i++) {
197  epicsGuard <PVRecord> guard(*pvr);
198  pvr->beginGroupPut();
199  pvr->process();
200  pvr->endGroupPut();
201  }
202  requester->processDone(Status::Ok,getPtrSelf());
203  } catch(std::exception& ex) {
204  Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
205  requester->processDone(status,getPtrSelf());
206  }
207 }
208 
209 class ChannelGetLocal :
210  public ChannelGet,
211  public std::tr1::enable_shared_from_this<ChannelGetLocal>
212 {
213 public:
214  POINTER_DEFINITIONS(ChannelGetLocal);
215  virtual ~ChannelGetLocal();
216  virtual void destroy() {} // DEPRECATED
217  static ChannelGetLocalPtr create(
218  ChannelLocalPtr const &channelLocal,
219  ChannelGetRequester::shared_pointer const & channelGetRequester,
220  PVStructurePtr const & pvRequest,
221  PVRecordPtr const &pvRecord);
222  virtual void get();
223  virtual std::tr1::shared_ptr<Channel> getChannel();
224  virtual void cancel(){}
225  virtual void lock();
226  virtual void unlock();
227  virtual void lastRequest() {}
228 private:
229  shared_pointer getPtrSelf()
230  {
231  return shared_from_this();
232  }
233  ChannelGetLocal(
234  bool callProcess,
235  ChannelLocalPtr const &channelLocal,
236  ChannelGetRequester::shared_pointer const & channelGetRequester,
237  PVCopyPtr const &pvCopy,
238  PVStructurePtr const&pvStructure,
239  BitSetPtr const & bitSet,
240  PVRecordPtr const &pvRecord)
241  :
242  firstTime(true),
243  callProcess(callProcess),
244  channelLocal(channelLocal),
245  channelGetRequester(channelGetRequester),
246  pvCopy(pvCopy),
247  pvStructure(pvStructure),
248  bitSet(bitSet),
249  pvRecord(pvRecord)
250  {
251  }
252  bool firstTime;
253  bool callProcess;
254  ChannelLocalWPtr channelLocal;
255  ChannelGetRequester::weak_pointer channelGetRequester;
256  PVCopyPtr pvCopy;
257  PVStructurePtr pvStructure;
258  BitSetPtr bitSet;
259  PVRecordWPtr pvRecord;
260  Mutex mutex;
261 };
262 
263 ChannelGetLocalPtr ChannelGetLocal::create(
264  ChannelLocalPtr const &channelLocal,
265  ChannelGetRequester::shared_pointer const & channelGetRequester,
266  PVStructurePtr const & pvRequest,
267  PVRecordPtr const &pvRecord)
268 {
269  PVCopyPtr pvCopy = PVCopy::create(
270  pvRecord->getPVRecordStructure()->getPVStructure(),
271  pvRequest,
272  "");
273  if(!pvCopy) {
274  Status status(
275  Status::STATUSTYPE_ERROR,
276  "invalid pvRequest");
277  ChannelGet::shared_pointer channelGet;
278  channelGetRequester->channelGetConnect(
279  status,
280  channelGet,
281  nullStructure);
282  ChannelGetLocalPtr localGet;
283  return localGet;
284  }
285  PVStructurePtr pvStructure = pvCopy->createPVStructure();
286  BitSetPtr bitSet(new BitSet(pvStructure->getNumberFields()));
287  ChannelGetLocalPtr get(new ChannelGetLocal(
288  getProcess(pvRequest,false),
289  channelLocal,
290  channelGetRequester,
291  pvCopy,
292  pvStructure,
293  bitSet,
294  pvRecord));
295  if(pvRecord->getTraceLevel()>0)
296  {
297  cout << "ChannelGetLocal::create";
298  cout << " recordName " << pvRecord->getRecordName() << endl;
299  }
300  channelGetRequester->channelGetConnect(
301  Status::Ok,get,pvStructure->getStructure());
302  return get;
303 }
304 
305 ChannelGetLocal::~ChannelGetLocal()
306 {
307  PVRecordPtr pvr(pvRecord.lock());
308  if(pvr && pvr->getTraceLevel()>0) {
309  cout << "~ChannelGetLocal() " << pvr->getRecordName() << endl;
310  }
311 }
312 
313 std::tr1::shared_ptr<Channel> ChannelGetLocal::getChannel()
314 {
315  ChannelLocalPtr channel(channelLocal.lock());
316  return channel;
317 }
318 
319 void ChannelGetLocal::lock()
320 {
321  PVRecordPtr pvr(pvRecord.lock());
322  if(!pvr) throw std::logic_error("pvRecord is deleted");
323  pvr->lock();
324 }
325 void ChannelGetLocal::unlock()
326 {
327  PVRecordPtr pvr(pvRecord.lock());
328  if(!pvr) throw std::logic_error("pvRecord is deleted");
329  pvr->unlock();
330 }
331 
332 
333 void ChannelGetLocal::get()
334 {
335  ChannelGetRequester::shared_pointer requester = channelGetRequester.lock();
336  if(!requester) return;
337  PVRecordPtr pvr(pvRecord.lock());
338  if(!pvr) throw std::logic_error("pvRecord is deleted");
339  try {
340  bool notifyClient = true;
341  bitSet->clear();
342  {
343  epicsGuard <PVRecord> guard(*pvr);
344  if(callProcess) {
345  pvr->beginGroupPut();
346  pvr->process();
347  pvr->endGroupPut();
348  }
349  notifyClient = pvCopy->updateCopySetBitSet(pvStructure, bitSet);
350  }
351  if(firstTime) {
352  bitSet->clear();
353  bitSet->set(0);
354  firstTime = false;
355  notifyClient = true;
356  }
357  if(notifyClient) {
358  requester->getDone(
359  Status::Ok,
360  getPtrSelf(),
361  pvStructure,
362  bitSet);
363  bitSet->clear();
364  } else {
365  BitSetPtr temp(new BitSet(bitSet->size()));
366  requester->getDone(
367  Status::Ok,
368  getPtrSelf(),
369  pvStructure,
370  temp);
371  }
372  if(pvr->getTraceLevel()>1)
373  {
374  cout << "ChannelGetLocal::get" << endl;
375  }
376  } catch(std::exception& ex) {
377  Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
378  requester->getDone(status,getPtrSelf(),pvStructure,bitSet);
379  }
380 
381 }
382 
383 class ChannelPutLocal :
384  public ChannelPut,
385  public std::tr1::enable_shared_from_this<ChannelPutLocal>
386 {
387 public:
388  POINTER_DEFINITIONS(ChannelPutLocal);
389  virtual ~ChannelPutLocal();
390  virtual void destroy() {} // DEPRECATED
391  static ChannelPutLocalPtr create(
392  ChannelLocalPtr const &channelLocal,
393  ChannelPutRequester::shared_pointer const & channelPutRequester,
394  PVStructurePtr const & pvRequest,
395  PVRecordPtr const &pvRecord);
396  virtual void put(PVStructurePtr const &pvStructure,BitSetPtr const &bitSet);
397  virtual void get();
398  virtual std::tr1::shared_ptr<Channel> getChannel();
399  virtual void cancel(){}
400  virtual void lock();
401  virtual void unlock();
402  virtual void lastRequest() {}
403 private:
404  shared_pointer getPtrSelf()
405  {
406  return shared_from_this();
407  }
408  ChannelPutLocal(
409  bool callProcess,
410  ChannelLocalPtr const &channelLocal,
411  ChannelPutRequester::shared_pointer const & channelPutRequester,
412  PVCopyPtr const &pvCopy,
413  PVRecordPtr const &pvRecord)
414  :
415  callProcess(callProcess),
416  channelLocal(channelLocal),
417  channelPutRequester(channelPutRequester),
418  pvCopy(pvCopy),
419  pvRecord(pvRecord)
420  {
421  }
422  bool callProcess;
423  ChannelLocalWPtr channelLocal;
424  ChannelPutRequester::weak_pointer channelPutRequester;
425  PVCopyPtr pvCopy;
426  PVRecordWPtr pvRecord;
427  Mutex mutex;
428 };
429 
430 ChannelPutLocalPtr ChannelPutLocal::create(
431  ChannelLocalPtr const &channelLocal,
432  ChannelPutRequester::shared_pointer const & channelPutRequester,
433  PVStructurePtr const & pvRequest,
434  PVRecordPtr const &pvRecord)
435 {
436  PVCopyPtr pvCopy = PVCopy::create(
437  pvRecord->getPVRecordStructure()->getPVStructure(),
438  pvRequest,
439  "");
440  if(!pvCopy) {
441  Status status(
442  Status::STATUSTYPE_ERROR,
443  "invalid pvRequest");
444  ChannelPut::shared_pointer channelPut;
445  PVStructurePtr pvStructure;
446  BitSetPtr bitSet;
447  channelPutRequester->channelPutConnect(
448  status,
449  channelPut,
450  nullStructure);
451  ChannelPutLocalPtr localPut;
452  return localPut;
453  }
454  ChannelPutLocalPtr put(new ChannelPutLocal(
455  getProcess(pvRequest,true),
456  channelLocal,
457  channelPutRequester,
458  pvCopy,
459  pvRecord));
460  channelPutRequester->channelPutConnect(
461  Status::Ok, put, pvCopy->getStructure());
462  if(pvRecord->getTraceLevel()>0)
463  {
464  cout << "ChannelPutLocal::create";
465  cout << " recordName " << pvRecord->getRecordName() << endl;
466  }
467  return put;
468 }
469 
470 ChannelPutLocal::~ChannelPutLocal()
471 {
472  PVRecordPtr pvr(pvRecord.lock());
473  if(pvr && pvr->getTraceLevel()>0) {
474  cout << "~ChannelPutLocal() " << pvr->getRecordName() << endl;
475  }
476 }
477 
478 std::tr1::shared_ptr<Channel> ChannelPutLocal::getChannel()
479 {
480  ChannelLocalPtr channel(channelLocal.lock());
481  return channel;
482 }
483 
484 void ChannelPutLocal::lock()
485 {
486  PVRecordPtr pvr(pvRecord.lock());
487  if(!pvr) throw std::logic_error("pvRecord is deleted");
488  pvr->lock();
489 }
490 void ChannelPutLocal::unlock()
491 {
492  PVRecordPtr pvr(pvRecord.lock());
493  if(!pvr) throw std::logic_error("pvRecord is deleted");
494  pvr->unlock();
495 }
496 
497 
498 void ChannelPutLocal::get()
499 {
500  ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
501  if(!requester) return;
502  PVRecordPtr pvr(pvRecord.lock());
503  if(!pvr) throw std::logic_error("pvRecord is deleted");
504  try {
505  PVStructurePtr pvStructure = pvCopy->createPVStructure();
506  BitSetPtr bitSet(new BitSet(pvStructure->getNumberFields()));
507  bitSet->clear();
508  bitSet->set(0);
509  {
510  epicsGuard <PVRecord> guard(*pvr);
511  pvCopy->updateCopyFromBitSet(pvStructure, bitSet);
512  }
513  requester->getDone(
514  Status::Ok,getPtrSelf(),pvStructure,bitSet);
515  if(pvr->getTraceLevel()>1)
516  {
517  cout << "ChannelPutLocal::get" << endl;
518  }
519  } catch(std::exception& ex) {
520  Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
521  PVStructurePtr pvStructure;
522  BitSetPtr bitSet;
523  requester->getDone(status,getPtrSelf(),pvStructure,bitSet);
524  }
525 }
526 
527 void ChannelPutLocal::put(
528  PVStructurePtr const &pvStructure,BitSetPtr const &bitSet)
529 {
530  ChannelPutRequester::shared_pointer requester = channelPutRequester.lock();
531  if(!requester) return;
532  PVRecordPtr pvr(pvRecord.lock());
533  if(!pvr) throw std::logic_error("pvRecord is deleted");
534  try {
535  {
536  epicsGuard <PVRecord> guard(*pvr);
537  pvr->beginGroupPut();
538  pvCopy->updateMaster(pvStructure, bitSet);
539  if(callProcess) {
540  pvr->process();
541  }
542  pvr->endGroupPut();
543  }
544  requester->putDone(Status::Ok,getPtrSelf());
545  if(pvr->getTraceLevel()>1)
546  {
547  cout << "ChannelPutLocal::put" << endl;
548  }
549  } catch(std::exception& ex) {
550  Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
551  requester->putDone(status,getPtrSelf());
552  }
553 }
554 
555 
556 class ChannelPutGetLocal :
557  public ChannelPutGet,
558  public std::tr1::enable_shared_from_this<ChannelPutGetLocal>
559 {
560 public:
561  POINTER_DEFINITIONS(ChannelPutGetLocal);
562  virtual ~ChannelPutGetLocal();
563  virtual void destroy() {} // DEPRECATED
564  static ChannelPutGetLocalPtr create(
565  ChannelLocalPtr const &channelLocal,
566  ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
567  PVStructurePtr const & pvRequest,
568  PVRecordPtr const &pvRecord);
569  virtual void putGet(
570  PVStructurePtr const &pvPutStructure,
571  BitSetPtr const &putBitSet);
572  virtual void getPut();
573  virtual void getGet();
574  virtual std::tr1::shared_ptr<Channel> getChannel();
575  virtual void cancel(){}
576  virtual void lock();
577  virtual void unlock();
578  virtual void lastRequest() {}
579 private:
580  shared_pointer getPtrSelf()
581  {
582  return shared_from_this();
583  }
584  ChannelPutGetLocal(
585  bool callProcess,
586  ChannelLocalPtr const &channelLocal,
587  ChannelPutGetRequester::weak_pointer const & channelPutGetRequester,
588  PVCopyPtr const &pvPutCopy,
589  PVCopyPtr const &pvGetCopy,
590  PVStructurePtr const&pvGetStructure,
591  BitSetPtr const & getBitSet,
592  PVRecordPtr const &pvRecord)
593  :
594  callProcess(callProcess),
595  channelLocal(channelLocal),
596  channelPutGetRequester(channelPutGetRequester),
597  pvPutCopy(pvPutCopy),
598  pvGetCopy(pvGetCopy),
599  pvGetStructure(pvGetStructure),
600  getBitSet(getBitSet),
601  pvRecord(pvRecord)
602  {
603  }
604  bool callProcess;
605  ChannelLocalWPtr channelLocal;
606  ChannelPutGetRequester::weak_pointer channelPutGetRequester;
607  PVCopyPtr pvPutCopy;
608  PVCopyPtr pvGetCopy;
609  PVStructurePtr pvGetStructure;
610  BitSetPtr getBitSet;
611  PVRecordWPtr pvRecord;
612  Mutex mutex;
613 };
614 
615 ChannelPutGetLocalPtr ChannelPutGetLocal::create(
616  ChannelLocalPtr const &channelLocal,
617  ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
618  PVStructurePtr const & pvRequest,
619  PVRecordPtr const &pvRecord)
620 {
621  PVCopyPtr pvPutCopy = PVCopy::create(
622  pvRecord->getPVRecordStructure()->getPVStructure(),
623  pvRequest,
624  "putField");
625  PVCopyPtr pvGetCopy = PVCopy::create(
626  pvRecord->getPVRecordStructure()->getPVStructure(),
627  pvRequest,
628  "getField");
629  if(!pvPutCopy || !pvGetCopy) {
630  Status status(
631  Status::STATUSTYPE_ERROR,
632  "invalid pvRequest");
633  ChannelPutGet::shared_pointer channelPutGet;
634  channelPutGetRequester->channelPutGetConnect(
635  status,
636  channelPutGet,
637  nullStructure,
638  nullStructure);
639  ChannelPutGetLocalPtr localPutGet;
640  return localPutGet;
641  }
642  PVStructurePtr pvGetStructure = pvGetCopy->createPVStructure();
643  BitSetPtr getBitSet(new BitSet(pvGetStructure->getNumberFields()));
644  ChannelPutGetLocalPtr putGet(new ChannelPutGetLocal(
645  getProcess(pvRequest,true),
646  channelLocal,
647  channelPutGetRequester,
648  pvPutCopy,
649  pvGetCopy,
650  pvGetStructure,
651  getBitSet,
652  pvRecord));
653  if(pvRecord->getTraceLevel()>0)
654  {
655  cout << "ChannelPutGetLocal::create";
656  cout << " recordName " << pvRecord->getRecordName() << endl;
657  }
658  channelPutGetRequester->channelPutGetConnect(
659  Status::Ok, putGet, pvPutCopy->getStructure(),pvGetCopy->getStructure());
660  return putGet;
661 }
662 
663 ChannelPutGetLocal::~ChannelPutGetLocal()
664 {
665  PVRecordPtr pvr(pvRecord.lock());
666  if(pvr && pvr->getTraceLevel()>0) {
667  cout << "~ChannelPutGetLocal() " << pvr->getRecordName() << endl;
668  }
669 }
670 
671 std::tr1::shared_ptr<Channel> ChannelPutGetLocal::getChannel()
672 {
673  ChannelLocalPtr channel(channelLocal.lock());
674  return channel;
675 }
676 
677 void ChannelPutGetLocal::lock()
678 {
679  PVRecordPtr pvr(pvRecord.lock());
680  if(!pvr) throw std::logic_error("pvRecord is deleted");
681  pvr->lock();
682 }
683 void ChannelPutGetLocal::unlock()
684 {
685  PVRecordPtr pvr(pvRecord.lock());
686  if(!pvr) throw std::logic_error("pvRecord is deleted");
687  pvr->unlock();
688 }
689 
690 
691 void ChannelPutGetLocal::putGet(
692  PVStructurePtr const &pvPutStructure,BitSetPtr const &putBitSet)
693 {
694  ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
695  if(!requester) return;
696  PVRecordPtr pvr(pvRecord.lock());
697  if(!pvr) throw std::logic_error("pvRecord is deleted");
698  try {
699  {
700  epicsGuard <PVRecord> guard(*pvr);
701  pvr->beginGroupPut();
702  pvPutCopy->updateMaster(pvPutStructure, putBitSet);
703  if(callProcess) pvr->process();
704  getBitSet->clear();
705  pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
706  pvr->endGroupPut();
707  }
708  requester->putGetDone(
709  Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
710  if(pvr->getTraceLevel()>1)
711  {
712  cout << "ChannelPutGetLocal::putGet" << endl;
713  }
714  } catch(std::exception& ex) {
715  Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
716  requester->putGetDone(status,getPtrSelf(),pvGetStructure,getBitSet);
717  }
718 }
719 
720 void ChannelPutGetLocal::getPut()
721 {
722  ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
723  if(!requester) return;
724  PVRecordPtr pvr(pvRecord.lock());
725  if(!pvr) throw std::logic_error("pvRecord is deleted");
726  try {
727  PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure();
728  BitSetPtr putBitSet(new BitSet(pvPutStructure->getNumberFields()));
729  {
730  epicsGuard <PVRecord> guard(*pvr);
731  pvPutCopy->initCopy(pvPutStructure, putBitSet);
732  }
733  requester->getPutDone(
734  Status::Ok,getPtrSelf(),pvPutStructure,putBitSet);
735  if(pvr->getTraceLevel()>1)
736  {
737  cout << "ChannelPutGetLocal::getPut" << endl;
738  }
739  } catch(std::exception& ex) {
740  Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
741  PVStructurePtr pvPutStructure;
742  BitSetPtr putBitSet;
743  requester->getPutDone(status,getPtrSelf(),pvGetStructure,getBitSet);
744  }
745 }
746 
747 void ChannelPutGetLocal::getGet()
748 {
749  ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock();
750  if(!requester) return;
751  PVRecordPtr pvr(pvRecord.lock());
752  if(!pvr) throw std::logic_error("pvRecord is deleted");
753  try {
754  getBitSet->clear();
755  {
756  epicsGuard <PVRecord> guard(*pvr);
757  pvGetCopy->updateCopySetBitSet(pvGetStructure, getBitSet);
758  }
759  requester->getGetDone(
760  Status::Ok,getPtrSelf(),pvGetStructure,getBitSet);
761  if(pvr->getTraceLevel()>1)
762  {
763  cout << "ChannelPutGetLocal::getGet" << endl;
764  }
765  } catch(std::exception& ex) {
766  Status status = Status(Status::STATUSTYPE_FATAL, ex.what());
767  PVStructurePtr pvPutStructure;
768  BitSetPtr putBitSet;
769  requester->getGetDone(status,getPtrSelf(),pvGetStructure,getBitSet);
770  }
771 }
772 
773 
774 class ChannelRPCLocal :
775  public ChannelRPC,
776  public RPCResponseCallback,
777  public std::tr1::enable_shared_from_this<ChannelRPCLocal>
778 {
779 public:
780  POINTER_DEFINITIONS(ChannelRPCLocal);
781  virtual void destroy() {} // DEPRECATED
782  static ChannelRPCLocalPtr create(
783  ChannelLocalPtr const & channelLocal,
784  ChannelRPCRequester::shared_pointer const & channelRPCRequester,
785  PVStructurePtr const & pvRequest,
786  PVRecordPtr const & pvRecord);
787 
788  ChannelRPCLocal(
789  ChannelLocalPtr const & channelLocal,
790  ChannelRPCRequester::shared_pointer const & channelRPCRequester,
791  RPCServiceAsync::shared_pointer const & service,
792  PVRecordPtr const & pvRecord) :
793  channelLocal(channelLocal),
794  channelRPCRequester(channelRPCRequester),
795  service(service),
796  pvRecord(pvRecord)
797  {
798  }
799 
800  virtual ~ChannelRPCLocal();
801  void processRequest(RPCService::shared_pointer const & service,
802  PVStructurePtr const & pvArgument);
803 
804  virtual void requestDone(Status const & status,
805  PVStructurePtr const & result)
806  {
807  ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
808  if(!requester) return;
809  requester->requestDone(status, getPtrSelf(), result);
810  }
811 
812  void processRequest(RPCServiceAsync::shared_pointer const & service,
813  PVStructurePtr const & pvArgument);
814 
815  virtual void request(PVStructurePtr const & pvArgument);
816  virtual Channel::shared_pointer getChannel();
817  virtual void cancel() {}
818  virtual void lock() {}
819  virtual void unlock() {}
820  virtual void lastRequest() {}
821 private:
822  shared_pointer getPtrSelf()
823  {
824  return shared_from_this();
825  }
826  ChannelLocalWPtr channelLocal;
827  ChannelRPCRequester::weak_pointer channelRPCRequester;
828  RPCServiceAsync::shared_pointer service;
829  PVRecordWPtr pvRecord;
830 };
831 
832 ChannelRPCLocalPtr ChannelRPCLocal::create(
833  ChannelLocalPtr const &channelLocal,
834  ChannelRPCRequester::shared_pointer const & channelRPCRequester,
835  PVStructurePtr const & pvRequest,
836  PVRecordPtr const &pvRecord)
837 {
838  RPCServiceAsync::shared_pointer service = pvRecord->getService(pvRequest);
839  if (!service)
840  {
841  Status status(Status::STATUSTYPE_ERROR,
842  "ChannelRPC not supported");
843  channelRPCRequester->channelRPCConnect(status,ChannelRPCLocalPtr());
844  return ChannelRPCLocalPtr();
845  }
846 
847  if (!channelRPCRequester)
848  throw std::invalid_argument("channelRPCRequester == null");
849 
850  // TODO use std::make_shared
851  ChannelRPCLocalPtr rpc(
852  new ChannelRPCLocal(channelLocal, channelRPCRequester, service, pvRecord)
853  );
854  channelRPCRequester->channelRPCConnect(Status::Ok, rpc);
855  if(pvRecord->getTraceLevel()>0)
856  {
857  cout << "ChannelRPCLocal::create";
858  cout << " recordName " << pvRecord->getRecordName() << endl;
859  }
860  return rpc;
861 }
862 
863 ChannelRPCLocal::~ChannelRPCLocal()
864 {
865  PVRecordPtr pvr(pvRecord.lock());
866  if(pvr && pvr->getTraceLevel()>0) {
867  cout << "~ChannelRPCLocal() " << pvr->getRecordName() << endl;
868  }
869 }
870 
871 std::tr1::shared_ptr<Channel> ChannelRPCLocal::getChannel()
872 {
873  ChannelLocalPtr channel(channelLocal.lock());
874  return channel;
875 }
876 
877 
878 void ChannelRPCLocal::processRequest(
879  RPCService::shared_pointer const & service,
880  PVStructurePtr const & pvArgument)
881 {
882  PVStructurePtr result;
883  Status status = Status::Ok;
884  bool ok = true;
885  try
886  {
887  result = service->request(pvArgument);
888  }
889  catch (RPCRequestException& rre)
890  {
891  status = Status(rre.getStatus(), rre.what());
892  ok = false;
893  }
894  catch (std::exception& ex)
895  {
896  status = Status(Status::STATUSTYPE_FATAL, ex.what());
897  ok = false;
898  }
899  catch (...)
900  {
901  // handle user unexpected errors
902  status = Status(Status::STATUSTYPE_FATAL, "Unexpected exception caught while calling RPCService.request(PVStructure).");
903  ok = false;
904  }
905 
906  // check null result
907  if (ok && !result)
908  {
909  status = Status(Status::STATUSTYPE_FATAL, "RPCService.request(PVStructure) returned null.");
910  }
911  ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
912  if(requester) requester->requestDone(status, getPtrSelf(), result);
913 }
914 
915 void ChannelRPCLocal::processRequest(
916  RPCServiceAsync::shared_pointer const & service,
917  PVStructurePtr const & pvArgument)
918 {
919  try
920  {
921  service->request(pvArgument, getPtrSelf());
922  }
923  catch (std::exception& ex)
924  {
925  // handle user unexpected errors
926  Status errorStatus(Status::STATUSTYPE_FATAL, ex.what());
927  ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
928  if(requester) requester->requestDone(errorStatus, getPtrSelf(), PVStructurePtr());
929  }
930  catch (...)
931  {
932  // handle user unexpected errors
933  Status errorStatus(Status::STATUSTYPE_FATAL,
934  "Unexpected exception caught while calling RPCServiceAsync.request(PVStructure, RPCResponseCallback).");
935  ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock();
936  if(requester) requester->requestDone(errorStatus, shared_from_this(), PVStructurePtr());
937  }
938 
939  // we wait for callback to be called
940 }
941 
942 
943 void ChannelRPCLocal::request(PVStructurePtr const & pvArgument)
944 {
945  PVRecordPtr pvr(pvRecord.lock());
946  if(pvr && pvr->getTraceLevel()>0) {
947  cout << "ChannelRPCLocal::request " << pvr->getRecordName() << endl;
948  }
949  RPCService::shared_pointer rpcService =
950  std::tr1::dynamic_pointer_cast<RPCService>(service);
951  if (rpcService)
952  {
953  processRequest(rpcService, pvArgument);
954  return;
955  }
956 
957  RPCServiceAsync::shared_pointer rpcServiceAsync =
958  std::tr1::dynamic_pointer_cast<RPCServiceAsync>(service);
959  if (rpcServiceAsync)
960  {
961  processRequest(rpcServiceAsync, pvArgument);
962  return;
963  }
964 }
965 
966 
967 typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
968 
969 class ChannelArrayLocal :
970  public ChannelArray,
971  public std::tr1::enable_shared_from_this<ChannelArrayLocal>
972 {
973 public:
974  POINTER_DEFINITIONS(ChannelArrayLocal);
975  virtual ~ChannelArrayLocal();
976  virtual void destroy() {} // DEPRECATED
977  static ChannelArrayLocalPtr create(
978  ChannelLocalPtr const &channelLocal,
979  ChannelArrayRequester::shared_pointer const & channelArrayRequester,
980  PVStructurePtr const & pvRequest,
981  PVRecordPtr const &pvRecord);
982  virtual void getArray(size_t offset, size_t count, size_t stride);
983  virtual void putArray(
984  PVArrayPtr const &putArray,
985  size_t offset, size_t count, size_t stride);
986  virtual void getLength();
987  virtual void setLength(size_t length);
988  virtual std::tr1::shared_ptr<Channel> getChannel();
989  virtual void cancel(){}
990  virtual void lock();
991  virtual void unlock();
992  virtual void lastRequest() {}
993 private:
994  shared_pointer getPtrSelf()
995  {
996  return shared_from_this();
997  }
998  ChannelArrayLocal(
999  ChannelLocalPtr const &channelLocal,
1000  ChannelArrayRequester::shared_pointer const & channelArrayRequester,
1001  PVArrayPtr const &pvArray,
1002  PVArrayPtr const &pvCopy,
1003  PVRecordPtr const &pvRecord)
1004  :
1005  channelLocal(channelLocal),
1006  channelArrayRequester(channelArrayRequester),
1007  pvArray(pvArray),
1008  pvCopy(pvCopy),
1009  pvRecord(pvRecord)
1010  {
1011  }
1012 
1013  ChannelLocalWPtr channelLocal;
1014  ChannelArrayRequester::weak_pointer channelArrayRequester;
1015  PVArrayPtr pvArray;
1016  PVArrayPtr pvCopy;
1017  PVRecordWPtr pvRecord;
1018  Mutex mutex;
1019 };
1020 
1021 
1022 ChannelArrayLocalPtr ChannelArrayLocal::create(
1023  ChannelLocalPtr const &channelLocal,
1024  ChannelArrayRequester::shared_pointer const & channelArrayRequester,
1025  PVStructurePtr const & pvRequest,
1026  PVRecordPtr const &pvRecord)
1027 {
1028  PVFieldPtrArray const & pvFields = pvRequest->getPVFields();
1029  if(pvFields.size()!=1) {
1030  Status status(
1031  Status::STATUSTYPE_ERROR,"invalid pvRequest");
1032  ChannelArrayLocalPtr channelArray;
1033  ArrayConstPtr array;
1034  channelArrayRequester->channelArrayConnect(status,channelArray,array);
1035  return channelArray;
1036  }
1037  PVFieldPtr pvField = pvFields[0];
1038  string fieldName("");
1039  while(true) {
1040  string name = pvField->getFieldName();
1041  if(fieldName.size()>0) fieldName += '.';
1042  fieldName += name;
1043  PVStructurePtr pvs = static_pointer_cast<PVStructure>(pvField);
1044  PVFieldPtrArray const & pvfs = pvs->getPVFields();
1045  if(pvfs.size()!=1) break;
1046  pvField = pvfs[0];
1047  }
1048  size_t indfield = fieldName.find_first_of("field.");
1049  if(indfield==0) {
1050  fieldName = fieldName.substr(6);
1051  }
1052  pvField = pvRecord->getPVRecordStructure()->getPVStructure()->getSubField(fieldName);
1053  if(!pvField) {
1054  Status status(
1055  Status::STATUSTYPE_ERROR,fieldName +" not found");
1056  ChannelArrayLocalPtr channelArray;
1057  ArrayConstPtr array;
1058  channelArrayRequester->channelArrayConnect(
1059  status,channelArray,array);
1060  return channelArray;
1061  }
1062  if(pvField->getField()->getType()!=scalarArray
1063  && pvField->getField()->getType()!=structureArray
1064  && pvField->getField()->getType()!=unionArray)
1065  {
1066  Status status(
1067  Status::STATUSTYPE_ERROR,fieldName +" not array");
1068  ChannelArrayLocalPtr channelArray;
1069  ArrayConstPtr array;
1070  channelArrayRequester->channelArrayConnect(
1071  status,channelArray,array);
1072  return channelArray;
1073  }
1074  PVArrayPtr pvArray = static_pointer_cast<PVArray>(pvField);
1075  PVArrayPtr pvCopy;
1076  if(pvField->getField()->getType()==scalarArray) {
1077  PVScalarArrayPtr xxx = static_pointer_cast<PVScalarArray>(pvField);
1078  pvCopy = getPVDataCreate()->createPVScalarArray(
1079  xxx->getScalarArray()->getElementType());
1080  } else if(pvField->getField()->getType()==structureArray) {
1081  PVStructureArrayPtr xxx = static_pointer_cast<PVStructureArray>(pvField);
1082  pvCopy = getPVDataCreate()->createPVStructureArray(
1083  xxx->getStructureArray()->getStructure());
1084  } else {
1085  PVUnionArrayPtr xxx = static_pointer_cast<PVUnionArray>(pvField);
1086  pvCopy = getPVDataCreate()->createPVUnionArray(
1087  xxx->getUnionArray()->getUnion());
1088  }
1089  ChannelArrayLocalPtr array(new ChannelArrayLocal(
1090  channelLocal,
1091  channelArrayRequester,
1092  pvArray,
1093  pvCopy,
1094  pvRecord));
1095  if(pvRecord->getTraceLevel()>0)
1096  {
1097  cout << "ChannelArrayLocal::create";
1098  cout << " recordName " << pvRecord->getRecordName() << endl;
1099  }
1100  channelArrayRequester->channelArrayConnect(
1101  Status::Ok, array, pvCopy->getArray());
1102  return array;
1103 }
1104 
1105 ChannelArrayLocal::~ChannelArrayLocal()
1106 {
1107  PVRecordPtr pvr(pvRecord.lock());
1108  if(pvr && pvr->getTraceLevel()>0) {
1109  cout << "~ChannelArrayLocal() " << pvr->getRecordName() << endl;
1110  }
1111 }
1112 
1113 std::tr1::shared_ptr<Channel> ChannelArrayLocal::getChannel()
1114 {
1115  ChannelLocalPtr channel(channelLocal.lock());
1116  return channel;
1117 }
1118 
1119 void ChannelArrayLocal::lock()
1120 {
1121  PVRecordPtr pvr(pvRecord.lock());
1122  if(!pvr) throw std::logic_error("pvRecord is deleted");
1123  pvr->lock();
1124 }
1125 void ChannelArrayLocal::unlock()
1126 {
1127  PVRecordPtr pvr(pvRecord.lock());
1128  if(!pvr) throw std::logic_error("pvRecord is deleted");
1129  pvr->unlock();
1130 }
1131 
1132 void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride)
1133 {
1134  ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1135  if(!requester) return;
1136  PVRecordPtr pvr(pvRecord.lock());
1137  if(!pvr) throw std::logic_error("pvRecord is deleted");
1138  if(pvr->getTraceLevel()>1)
1139  {
1140  cout << "ChannelArrayLocal::getArray" << endl;
1141  }
1142  const char *exceptionMessage = NULL;
1143  try {
1144  bool ok = false;
1145  epicsGuard <PVRecord> guard(*pvr);
1146  while(true) {
1147  size_t length = pvArray->getLength();
1148  if(length<=0) break;
1149  if(count<=0) {
1150  count = (length -offset + stride -1)/stride;
1151  if(count>0) ok = true;
1152  break;
1153  }
1154  size_t maxcount = (length -offset + stride -1)/stride;
1155  if(count>maxcount) count = maxcount;
1156  ok = true;
1157  break;
1158  }
1159  if(ok) {
1160  pvCopy->setLength(count);
1161  copy(pvArray,offset,stride,pvCopy,0,1,count);
1162  }
1163  } catch(std::exception& e) {
1164  exceptionMessage = e.what();
1165  }
1166  Status status = Status::Ok;
1167  if(exceptionMessage!=NULL) {
1168  status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1169  }
1170  requester->getArrayDone(status,getPtrSelf(),pvCopy);
1171 }
1172 
1173 void ChannelArrayLocal::putArray(
1174  PVArrayPtr const & pvArray, size_t offset, size_t count, size_t stride)
1175 {
1176  ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1177  if(!requester) return;
1178  PVRecordPtr pvr(pvRecord.lock());
1179  if(!pvr) throw std::logic_error("pvRecord is deleted");
1180  if(pvr->getTraceLevel()>1)
1181  {
1182  cout << "ChannelArrayLocal::putArray" << endl;
1183  }
1184  size_t newLength = offset + count*stride;
1185  if(newLength<pvArray->getLength()) pvArray->setLength(newLength);
1186  const char *exceptionMessage = NULL;
1187  try {
1188  epicsGuard <PVRecord> guard(*pvr);
1189  copy(pvArray,0,1,this->pvArray,offset,stride,count);
1190  } catch(std::exception& e) {
1191  exceptionMessage = e.what();
1192  }
1193  Status status = Status::Ok;
1194  if(exceptionMessage!=NULL) {
1195  status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1196  }
1197  requester->putArrayDone(status,getPtrSelf());
1198 }
1199 
1200 void ChannelArrayLocal::getLength()
1201 {
1202  ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1203  if(!requester) return;
1204  PVRecordPtr pvr(pvRecord.lock());
1205  if(!pvr) throw std::logic_error("pvRecord is deleted");
1206  size_t length = 0;
1207  const char *exceptionMessage = NULL;
1208  try {
1209  epicsGuard <PVRecord> guard(*pvr);
1210  length = pvArray->getLength();
1211  } catch(std::exception& e) {
1212  exceptionMessage = e.what();
1213  }
1214  Status status = Status::Ok;
1215  if(exceptionMessage!=NULL) {
1216  status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1217  }
1218  requester->getLengthDone(status,getPtrSelf(),length);
1219 }
1220 
1221 void ChannelArrayLocal::setLength(size_t length)
1222 {
1223  ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock();
1224  if(!requester) return;
1225  PVRecordPtr pvr(pvRecord.lock());
1226  if(!pvr) throw std::logic_error("pvRecord is deleted");
1227  if(pvr->getTraceLevel()>1)
1228  {
1229  cout << "ChannelArrayLocal::setLength" << endl;
1230  }
1231  try {
1232  {
1233  epicsGuard <PVRecord> guard(*pvr);
1234  if(pvArray->getLength()!=length) pvArray->setLength(length);
1235  }
1236  requester->setLengthDone(Status::Ok,getPtrSelf());
1237  } catch(std::exception& e) {
1238  string exceptionMessage = e.what();
1239  Status status = Status(Status::STATUSTYPE_ERROR,exceptionMessage);
1240  requester->setLengthDone(status,getPtrSelf());
1241  }
1242 }
1243 
1244 
1245 ChannelLocal::ChannelLocal(
1246  ChannelProviderLocalPtr const & provider,
1247  ChannelRequester::shared_pointer const & requester,
1248  PVRecordPtr const & pvRecord)
1249 :
1250  requester(requester),
1251  provider(provider),
1252  pvRecord(pvRecord)
1253 {
1254  if(pvRecord->getTraceLevel()>0) {
1255  cout << "ChannelLocal::ChannelLocal()"
1256  << " recordName " << pvRecord->getRecordName()
1257  << " requester exists " << (requester ? "true" : "false")
1258  << endl;
1259  }
1260 }
1261 
1263 {
1264  PVRecordPtr pvr(pvRecord.lock());
1265  if(!pvr) return;
1266  if(pvr->getTraceLevel()>0)
1267  {
1268  cout << "~ChannelLocal()" << endl;
1269  }
1270 }
1271 
1272 ChannelProvider::shared_pointer ChannelLocal::getProvider()
1273 {
1274  return provider.lock();
1275 }
1276 
1277 void ChannelLocal::detach(PVRecordPtr const & pvRecord)
1278 {
1279  if(pvRecord->getTraceLevel()>0) {
1280  cout << "ChannelLocal::detach() "
1281  << " recordName " << pvRecord->getRecordName()
1282  << " requester exists " << (requester ? "true" : "false")
1283  << endl;
1284  }
1285  if(!requester) return;
1286  requester->channelStateChange(shared_from_this(),Channel::DESTROYED);
1287 }
1288 
1289 
1291 {
1292  PVRecordPtr pvr(pvRecord.lock());
1293  if(pvr && pvr->getTraceLevel()>0) {
1294  cout << "ChannelLocal::getRequesterName() "
1295  << " recordName " << pvr->getRecordName()
1296  << " requester exists " << (requester ? "true" : "false")
1297  << endl;
1298  }
1299 
1300  if(!requester) return string();
1301  return requester->getRequesterName();
1302 }
1303 
1305  string const &message,
1306  MessageType messageType)
1307 {
1308  PVRecordPtr pvr(pvRecord.lock());
1309  if(pvr && pvr->getTraceLevel()>1) {
1310  cout << "ChannelLocal::message() "
1311  << " recordName " << pvr->getRecordName()
1312  << " requester exists " << (requester ? "true" : "false")
1313  << endl;
1314  }
1315  if(requester) {
1316  requester->message(message,messageType);
1317  return;
1318  }
1319  string recordName("record deleted");
1320  if(pvr) recordName = pvr->getRecordName();
1321  cout << recordName
1322  << " message " << message
1323  << " messageType " << getMessageTypeName(messageType)
1324  << endl;
1325 }
1326 
1328 {
1329  return string("local");
1330 }
1331 
1332 Channel::ConnectionState ChannelLocal::getConnectionState()
1333 {
1334  return Channel::CONNECTED;
1335 }
1336 
1338 {
1339  PVRecordPtr pvr(pvRecord.lock());
1340  string name("record deleted");
1341  if(pvr) name = pvr->getRecordName();
1342  return name;
1343 }
1344 
1345 ChannelRequester::shared_pointer ChannelLocal::getChannelRequester()
1346 {
1347  return requester;
1348 }
1349 
1351 {
1352  return true;
1353 }
1354 
1355 void ChannelLocal::getField(GetFieldRequester::shared_pointer const &requester,
1356  string const &subField)
1357 {
1358  PVRecordPtr pvr(pvRecord.lock());
1359  if(!pvr) throw std::logic_error("pvRecord is deleted");
1360  if(subField.size()<1) {
1361  StructureConstPtr structure =
1362  pvr->getPVRecordStructure()->getPVStructure()->getStructure();
1363  requester->getDone(Status::Ok,structure);
1364  return;
1365  }
1366  PVFieldPtr pvField =
1367  pvr->getPVRecordStructure()->getPVStructure()->getSubField(subField);
1368  if(pvField) {
1369  requester->getDone(Status::Ok,pvField->getField());
1370  return;
1371  }
1372  Status status(Status::STATUSTYPE_ERROR,
1373  "client asked for illegal field");
1374  requester->getDone(status,FieldConstPtr());
1375 }
1376 
1378  PVField::shared_pointer const &pvField)
1379 {
1380  throw std::logic_error("Not Implemented");
1381 }
1382 
1383 ChannelProcess::shared_pointer ChannelLocal::createChannelProcess(
1384  ChannelProcessRequester::shared_pointer const & channelProcessRequester,
1385  PVStructure::shared_pointer const & pvRequest)
1386 {
1387  PVRecordPtr pvr(pvRecord.lock());
1388  if(!pvr) throw std::logic_error("pvRecord is deleted");
1389  if(pvr->getTraceLevel()>0) {
1390  cout << "ChannelLocal::createChannelProcess() "
1391  << " recordName " << pvr->getRecordName()
1392  << " requester exists " << (requester ? "true" : "false")
1393  << endl;
1394  }
1395  ChannelProcessLocalPtr channelProcess =
1396  ChannelProcessLocal::create(
1397  getPtrSelf(),
1398  channelProcessRequester,
1399  pvRequest,
1400  pvr);
1401  return channelProcess;
1402 }
1403 
1404 ChannelGet::shared_pointer ChannelLocal::createChannelGet(
1405  ChannelGetRequester::shared_pointer const &channelGetRequester,
1406  PVStructure::shared_pointer const &pvRequest)
1407 {
1408  PVRecordPtr pvr(pvRecord.lock());
1409  if(!pvr) throw std::logic_error("pvRecord is deleted");
1410  if(pvr->getTraceLevel()>0) {
1411  cout << "ChannelLocal::createChannelGet() "
1412  << " recordName " << pvr->getRecordName()
1413  << " requester exists " << (requester ? "true" : "false")
1414  << endl;
1415  }
1416  ChannelGetLocalPtr channelGet =
1417  ChannelGetLocal::create(
1418  getPtrSelf(),
1419  channelGetRequester,
1420  pvRequest,
1421  pvr);
1422  return channelGet;
1423 }
1424 
1425 ChannelPut::shared_pointer ChannelLocal::createChannelPut(
1426  ChannelPutRequester::shared_pointer const &channelPutRequester,
1427  PVStructure::shared_pointer const &pvRequest)
1428 {
1429  PVRecordPtr pvr(pvRecord.lock());
1430  if(!pvr) throw std::logic_error("pvRecord is deleted");
1431  if(pvr->getTraceLevel()>0) {
1432  cout << "ChannelLocal::createChannelPut() "
1433  << " recordName " << pvr->getRecordName()
1434  << " requester exists " << (requester ? "true" : "false")
1435  << endl;
1436  }
1437 
1438  ChannelPutLocalPtr channelPut =
1439  ChannelPutLocal::create(
1440  getPtrSelf(),
1441  channelPutRequester,
1442  pvRequest,
1443  pvr);
1444  return channelPut;
1445 }
1446 
1447 ChannelPutGet::shared_pointer ChannelLocal::createChannelPutGet(
1448  ChannelPutGetRequester::shared_pointer const &channelPutGetRequester,
1449  PVStructure::shared_pointer const &pvRequest)
1450 {
1451  PVRecordPtr pvr(pvRecord.lock());
1452  if(!pvr) throw std::logic_error("pvRecord is deleted");
1453  if(pvr->getTraceLevel()>0) {
1454  cout << "ChannelLocal::createChannelPutGet() "
1455  << " recordName " << pvr->getRecordName()
1456  << " requester exists " << (requester ? "true" : "false")
1457  << endl;
1458  }
1459 
1460  ChannelPutGetLocalPtr channelPutGet =
1461  ChannelPutGetLocal::create(
1462  getPtrSelf(),
1463  channelPutGetRequester,
1464  pvRequest,
1465  pvr);
1466  return channelPutGet;
1467 }
1468 
1469 ChannelRPC::shared_pointer ChannelLocal::createChannelRPC(
1470  ChannelRPCRequester::shared_pointer const & channelRPCRequester,
1471  PVStructure::shared_pointer const & pvRequest)
1472 {
1473  PVRecordPtr pvr(pvRecord.lock());
1474  if(!pvr) throw std::logic_error("pvRecord is deleted");
1475  if(pvr->getTraceLevel()>0) {
1476  cout << "ChannelLocal::createChannelRPC() "
1477  << " recordName " << pvr->getRecordName()
1478  << " requester exists " << (requester ? "true" : "false")
1479  << endl;
1480  }
1481 
1482  ChannelRPCLocalPtr channelRPC =
1483  ChannelRPCLocal::create(
1484  getPtrSelf(),
1485  channelRPCRequester,
1486  pvRequest,
1487  pvr);
1488  return channelRPC;
1489 }
1490 
1491 Monitor::shared_pointer ChannelLocal::createMonitor(
1492  MonitorRequester::shared_pointer const &monitorRequester,
1493  PVStructure::shared_pointer const &pvRequest)
1494 {
1495  PVRecordPtr pvr(pvRecord.lock());
1496  if(!pvr) throw std::logic_error("pvRecord is deleted");
1497  if(pvr->getTraceLevel()>0) {
1498  cout << "ChannelLocal::createMonitor() "
1499  << " recordName " << pvr->getRecordName()
1500  << " requester exists " << (requester ? "true" : "false")
1501  << endl;
1502  }
1503 
1504  MonitorPtr monitor = createMonitorLocal(
1505  pvr,
1506  monitorRequester,
1507  pvRequest);
1508  return monitor;
1509 }
1510 
1511 ChannelArray::shared_pointer ChannelLocal::createChannelArray(
1512  ChannelArrayRequester::shared_pointer const &channelArrayRequester,
1513  PVStructure::shared_pointer const &pvRequest)
1514 {
1515  PVRecordPtr pvr(pvRecord.lock());
1516  if(!pvr) throw std::logic_error("pvRecord is deleted");
1517  if(pvr->getTraceLevel()>0) {
1518  cout << "ChannelLocal::createChannelArray() "
1519  << " recordName " << pvr->getRecordName()
1520  << " requester exists " << (requester ? "true" : "false")
1521  << endl;
1522  }
1523  ChannelArrayLocalPtr channelArray =
1524  ChannelArrayLocal::create(
1525  getPtrSelf(),
1526  channelArrayRequester,
1527  pvRequest,
1528  pvr);
1529  return channelArray;
1530 }
1531 
1533 {
1534  printInfo(std::cout);
1535 }
1536 
1537 void ChannelLocal::printInfo(std::ostream& out)
1538 {
1539  out << "ChannelLocal provides access to a record in the local PVDatabase";
1540 }
1541 
1542 }}
virtual void printInfo()
calls printInfo(std::cout);
virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelPut.
std::tr1::shared_ptr< PVCopy > PVCopyPtr
Definition: pvPlugin.h:25
virtual std::string getRequesterName()
Get the requester name.
std::tr1::shared_ptr< ChannelRPCLocal > ChannelRPCLocalPtr
std::tr1::shared_ptr< ChannelLocal > ChannelLocalPtr
std::tr1::shared_ptr< PVArray > PVArrayPtr
virtual ~ChannelLocal()
Destructor.
std::tr1::weak_ptr< ChannelLocal > ChannelLocalWPtr
virtual void getField(epics::pvAccess::GetFieldRequester::shared_pointer const &requester, std::string const &subField)
Get the introspection interface for subField.
virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC(epics::pvAccess::ChannelRPCRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelRPC.
virtual epics::pvData::Monitor::shared_pointer createMonitor(epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a monitor.
virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray(epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelArray.
epicsShareFunc epics::pvData::MonitorPtr createMonitorLocal(PVRecordPtr const &pvRecord, epics::pvData::MonitorRequester::shared_pointer const &monitorRequester, epics::pvData::PVStructurePtr const &pvRequest)
std::tr1::shared_ptr< ChannelProviderLocal > ChannelProviderLocalPtr
virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet(epics::pvAccess::ChannelPutGetRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelPutGet.
virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider()
Get the channel provider.
virtual epics::pvAccess::AccessRights getAccessRights(epics::pvData::PVField::shared_pointer const &pvField)
std::tr1::shared_ptr< ChannelPutGetLocal > ChannelPutGetLocalPtr
std::tr1::shared_ptr< PVRecord > PVRecordPtr
Definition: pvDatabase.h:21
std::tr1::shared_ptr< ChannelArrayLocal > ChannelArrayLocalPtr
std::tr1::shared_ptr< ChannelProcessLocal > ChannelProcessLocalPtr
std::tr1::shared_ptr< ChannelGetLocal > ChannelGetLocalPtr
virtual std::string getChannelName()
Get the channel name.
std::tr1::weak_ptr< PVRecord > PVRecordWPtr
Definition: pvDatabase.h:23
virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess(epics::pvAccess::ChannelProcessRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelProcess.
virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(epics::pvAccess::ChannelGetRequester::shared_pointer const &requester, epics::pvData::PVStructurePtr const &pvRequest)
Create a channelGet.
std::tr1::shared_ptr< ChannelPutLocal > ChannelPutLocalPtr
virtual bool isConnected()
Is the channel connected?
virtual void message(std::string const &message, epics::pvData::MessageType messageType)
Passes the message to the channel requester.
virtual std::string getRemoteAddress()
Get the remote address.
virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester()
Get the channel requester.
virtual epics::pvAccess::Channel::ConnectionState getConnectionState()
virtual void detach(PVRecordPtr const &pvRecord)
Detach from the record.