This is Unofficial EPICS BASE Doxygen Site
PVAServerRegister.cpp
Go to the documentation of this file.
1 /*PVAServerRegister.cpp */
12 /* Author: Marty Kraimer */
13 
14 #include <cstddef>
15 #include <cstdlib>
16 #include <cstddef>
17 #include <string>
18 #include <cstdio>
19 #include <memory>
20 #include <iostream>
21 
22 #include <cantProceed.h>
23 #include <epicsStdio.h>
24 #include <epicsMutex.h>
25 #include <epicsEvent.h>
26 #include <epicsThread.h>
27 #include <iocsh.h>
28 #include <initHooks.h>
29 #include <epicsExit.h>
30 
31 #include <pv/pvAccess.h>
32 #include <pv/serverContext.h>
33 #include <pv/iocshelper.h>
34 
35 #include <epicsExport.h>
36 
37 namespace pvd = epics::pvData;
38 namespace pva = epics::pvAccess;
39 
40 namespace {
41 
42 pvd::Mutex the_server_lock;
43 pva::ServerContext::shared_pointer the_server;
44 
45 void startitup() {
46  the_server = pva::ServerContext::create(pva::ServerContext::Config()
48  // default to all providers instead of just "local"
49  .add("EPICS_PVAS_PROVIDER_NAMES", pva::PVACCESS_ALL_PROVIDERS)
50  .push_map()
51  // prefer to use EPICS_PVAS_PROVIDER_NAMES
52  // from environment
53  .push_env()
54  .build()));
55 }
56 
57 void startPVAServer(const char *names)
58 {
59  try {
60  if(names && names[0]!='\0') {
61  printf("Warning: startPVAServer() no longer accepts provider list as argument.\n"
62  " Instead place the following before calling startPVAServer() and iocInit()\n"
63  " epicsEnvSet(\"EPICS_PVAS_PROVIDER_NAMES\", \"%s\")\n",
64  names);
65  }
66  pvd::Lock G(the_server_lock);
67  if(the_server) {
68  std::cout<<"PVA server already running\n";
69  return;
70  }
71  startitup();
72  }catch(std::exception& e){
73  std::cout<<"Error: "<<e.what()<<"\n";
74  }
75 }
76 
77 void stopPVAServer()
78 {
79  try {
80  pvd::Lock G(the_server_lock);
81  if(!the_server) {
82  std::cout<<"PVA server not running\n";
83  return;
84  }
85  the_server.reset();
86  }catch(std::exception& e){
87  std::cout<<"Error: "<<e.what()<<"\n";
88  }
89 }
90 
91 void pvasr(int lvl)
92 {
93  try {
94  pva::ServerContext::shared_pointer serv;
95  {
96  pvd::Lock G(the_server_lock);
97  serv = the_server;
98  }
99  if(!serv) {
100  std::cout<<"PVA server not running\n";
101  } else {
102  serv->printInfo(lvl);
103  }
104  std::cout.flush();
105  }catch(std::exception& e){
106  std::cout<<"Error: "<<e.what()<<std::endl;
107  }
108 }
109 
110 namespace {
111 struct DummyLister : public pva::ChannelListRequester
112 {
113  const std::string pname;
114  const int lvl;
115  DummyLister(const std::string& pname, int lvl) :pname(pname), lvl(lvl) {}
116  virtual ~DummyLister() {}
117 
118  // ChannelListRequester interface
119 public:
120  virtual void channelListResult(const pvd::Status &status,
121  const pva::ChannelFind::shared_pointer &channelFind,
122  const pvd::PVStringArray::const_svector &channelNames,
123  bool hasDynamic) OVERRIDE FINAL
124  {
125  if(lvl)
126  printf("#Provider: \"%s\"%s\n", pname.c_str(), hasDynamic ? " dynamic" : "");
127  if(lvl && !status.isSuccess())
128  printf("#Message: %s\n", status.getMessage().c_str());
129  for(size_t i=0, N=channelNames.size(); i<N; i++)
130  printf("%s\n", channelNames[i].c_str());
131  }
132 };
133 } // namespace
134 
135 void pval(int lvl)
136 {
137  try {
138  pva::ServerContext::shared_pointer serv;
139  {
140  pvd::Lock G(the_server_lock);
141  serv = the_server;
142  }
143  if(!serv) {
144  std::cout<<"PVA server not running\n";
145  } else {
146  const std::vector<pva::ChannelProvider::shared_pointer>& providers = serv->getChannelProviders();
147 
148  for(size_t p=0, P=providers.size(); p<P; p++)
149  {
150  std::tr1::shared_ptr<DummyLister> lister(new DummyLister(providers[p]->getProviderName(), lvl));
151  (void)providers[p]->channelList(lister);
152  }
153  }
154 
155  }catch(std::exception& e){
156  std::cout<<"Error: "<<e.what()<<std::endl;
157  }
158 }
159 
160 void pva_server_cleanup(void *)
161 {
162  stopPVAServer();
163 }
164 
165 void initStartPVAServer(initHookState state)
166 {
167  pvd::Lock G(the_server_lock);
168  if(state==initHookAfterIocRunning && !the_server) {
169  epicsAtExit(&pva_server_cleanup, 0);
170  startitup();
171 
172  } else if(state==initHookAtIocPause) {
173  the_server.reset();
174  }
175 }
176 
177 void registerStartPVAServer(void)
178 {
179  epics::iocshRegister<const char*, &startPVAServer>("startPVAServer", "provider names");
180  epics::iocshRegister<&stopPVAServer>("stopPVAServer");
181  epics::iocshRegister<int, &pvasr>("pvasr", "detail");
182  epics::iocshRegister<int, &pval>("pval", "detail");
183  initHookRegister(&initStartPVAServer);
184 }
185 
186 } // namespace
187 
188 extern "C" {
189  epicsExportRegistrar(registerStartPVAServer);
190 }
pvd::Status status
int i
Definition: scan.c:967
#define printf
Definition: epicsStdio.h:41
A lock for multithreading.
Definition: lock.h:36
#define OVERRIDE
Definition: pvAccess.h:55
const std::string & getMessage() const
Definition: status.h:80
Holds all PVA related.
Definition: pvif.h:34
pvData
Definition: monitor.h:428
APIs for the epicsMutex mutual exclusion semaphore.
bool isSuccess() const
Definition: status.h:103
Extended replacement for the Posix exit and atexit routines.
APIs for the epicsEvent binary semaphore.
int initHookRegister(initHookFunction func)
Definition: initHooks.c:51
epicsShareFunc ServerContext::shared_pointer startPVAServer(std::string const &providerNames=PVACCESS_ALL_PROVIDERS, int timeToRun=0, bool runInSeparateThread=false, bool printInfo=false)
initHookState
Definition: initHooks.h:25
static ServerContext::shared_pointer create(const Config &conf=Config())
Routines for code that can&#39;t continue or return after an error.
epicsShareExtern const std::string PVACCESS_ALL_PROVIDERS
Definition: pvaConstants.h:85
epicsExportRegistrar(registerStartPVAServer)
const std::string pname
#define epicsAtExit(F, A)
Convenience macro to register a function and context value to be run when the process exits...
Definition: epicsExit.h:70
epicsMutex Mutex
Definition: lock.h:28
C++ and C descriptions for a thread.
#define FINAL
Definition: pvAccess.h:48
Exporting IOC objects.
::epics::pvData::shared_vector< const T > const_svector
Definition: pvData.h:1185