pva2pva  1.4.1
 All Classes Functions Variables Pages
qsrv.cpp
1 
2 #include <initHooks.h>
3 #include <epicsExit.h>
4 #include <epicsThread.h>
5 #include <epicsString.h>
6 #include <epicsStdio.h>
7 
8 #include <dbAccess.h>
9 #include <dbChannel.h>
10 #include <dbStaticLib.h>
11 #include <dbLock.h>
12 #include <dbEvent.h>
13 #include <epicsVersion.h>
14 #include <dbNotify.h>
15 
16 #include <pv/reftrack.h>
17 #include <pv/pvAccess.h>
18 #include <pv/serverContext.h>
19 #include <pv/iocshelper.h>
20 
21 #include "pv/qsrv.h"
22 #include "pvahelper.h"
23 #include "pvif.h"
24 #include "pdb.h"
25 #include "pdbsingle.h"
26 #ifdef USE_MULTILOCK
27 # include "pdbgroup.h"
28 #endif
29 
30 #include <epicsExport.h>
31 
32 namespace pva = epics::pvAccess;
33 
34 void QSRVRegistrar_counters()
35 {
36  epics::registerRefCounter("PDBSinglePV", &PDBSinglePV::num_instances);
37  epics::registerRefCounter("PDBSingleChannel", &PDBSingleChannel::num_instances);
38  epics::registerRefCounter("PDBSinglePut", &PDBSinglePut::num_instances);
39  epics::registerRefCounter("PDBSingleMonitor", &PDBSingleMonitor::num_instances);
40 #ifdef USE_MULTILOCK
41  epics::registerRefCounter("PDBGroupPV", &PDBGroupPV::num_instances);
42  epics::registerRefCounter("PDBGroupChannel", &PDBGroupChannel::num_instances);
43  epics::registerRefCounter("PDBGroupPut", &PDBGroupPut::num_instances);
44  epics::registerRefCounter("PDBGroupMonitor", &PDBGroupMonitor::num_instances);
45 #endif // USE_MULTILOCK
46  epics::registerRefCounter("PDBProvider", &PDBProvider::num_instances);
47 }
48 
49 long dbLoadGroup(const char* fname)
50 {
51  try {
52  if(!fname) {
53  printf("dbLoadGroup(\"file.json\")\n"
54  "\n"
55  "Load additional DB group definitions from file.\n");
56  return 1;
57  }
58 #ifndef USE_MULTILOCK
59  static bool warned;
60  if(!warned) {
61  warned = true;
62  fprintf(stderr, "ignoring %s\n", fname);
63  }
64 #endif
65 
66  if(fname[0]=='-') {
67  fname++;
68  if(fname[0]=='*' && fname[1]=='\0') {
69  PDBProvider::group_files.clear();
70  } else {
71  PDBProvider::group_files.remove(fname);
72  }
73  } else {
74  PDBProvider::group_files.remove(fname);
75  PDBProvider::group_files.push_back(fname);
76  }
77 
78  return 0;
79  }catch(std::exception& e){
80  fprintf(stderr, "Error: %s\n", e.what());
81  return 1;
82  }
83 }
84 
85 namespace {
86 
87 void dbLoadGroupWrap(const char* fname)
88 {
89  (void)dbLoadGroup(fname);
90 }
91 
92 void dbgl(int lvl, const char *pattern)
93 {
94  if(!pattern)
95  pattern = "";
96 
97  try {
98  PDBProvider::shared_pointer prov(
99  std::tr1::dynamic_pointer_cast<PDBProvider>(
100  pva::ChannelProviderRegistry::servers()->getProvider("QSRV")));
101  if(!prov)
102  throw std::runtime_error("No Provider (PVA server not running?)");
103 
104  PDBProvider::persist_pv_map_t pvs;
105  {
106  epicsGuard<epicsMutex> G(prov->transient_pv_map.mutex());
107  pvs = prov->persist_pv_map; // copy map
108  }
109 
110  for(PDBProvider::persist_pv_map_t::const_iterator it(pvs.begin()), end(pvs.end());
111  it != end; ++it)
112  {
113  if(pattern[0] && epicsStrGlobMatch(it->first.c_str(), pattern)==0)
114  continue;
115 
116  printf("%s\n", it->first.c_str());
117  if(lvl<=0)
118  continue;
119  it->second->show(lvl);
120  }
121 
122  }catch(std::exception& e){
123  fprintf(stderr, "Error: %s\n", e.what());
124  }
125 }
126 
127 void QSRVRegistrar()
128 {
129  QSRVRegistrar_counters();
130  pva::ChannelProviderRegistry::servers()->addSingleton<PDBProvider>("QSRV");
131  epics::iocshRegister<int, const char*, &dbgl>("dbgl", "level", "pattern");
132  epics::iocshRegister<const char*, &dbLoadGroupWrap>("dbLoadGroup", "jsonfile");
133 }
134 
135 } // namespace
136 
137 unsigned qsrvVersion(void)
138 {
139  return QSRV_VERSION_INT;
140 }
141 
142 unsigned qsrvABIVersion(void)
143 {
144  return QSRV_ABI_VERSION_INT;
145 }
146 
147 extern "C" {
148  epicsExportRegistrar(QSRVRegistrar);
149 }