This is Unofficial EPICS BASE Doxygen Site
pvalink.cpp File Reference
#include <set>
#include <map>
#include <epicsGuard.h>
#include <dbAccess.h>
#include <dbCommon.h>
#include <dbLink.h>
#include <dbScan.h>
#include <errlog.h>
#include <initHooks.h>
#include <alarm.h>
#include <epicsExit.h>
#include <epicsAtomic.h>
#include <link.h>
#include <dbJLink.h>
#include <epicsUnitTest.h>
#include <epicsString.h>
#include <epicsStdio.h>
#include <pv/pvAccess.h>
#include <pv/clientFactory.h>
#include <pv/iocshelper.h>
#include <pv/reftrack.h>
#include <pva/client.h>
#include "pv/qsrv.h"
#include "helper.h"
#include "pvif.h"
#include "pvalink.h"
#include <epicsExport.h>
+ Include dependency graph for pvalink.cpp:

Go to the source code of this file.

Macros

#define EPICS_DBCA_PRIVATE_API
 

Functions

void testqsrvShutdownOk (void)
 
void testqsrvCleanup (void)
 
void testqsrvWaitForLinkEvent (struct link *plink)
 
void dbpvar (const char *precordname, int level)
 
 epicsExportRegistrar (installPVAAddLinkHook)
 
 epicsExportAddress (jlif, lsetPVA)
 
 epicsExportAddress (int, pvaLinkDebug)
 
 epicsExportAddress (int, pvaLinkNWorkers)
 

Variables

int pvaLinkDebug
 
int pvaLinkIsolate
 

Macro Definition Documentation

#define EPICS_DBCA_PRIVATE_API

Definition at line 5 of file pvalink.cpp.

Function Documentation

void dbpvar ( const char *  precordname,
int  level 
)

Definition at line 185 of file pvalink.cpp.

186 {
187  try {
188  if(!pvaGlobal) {
189  printf("PVA links not initialized\n");
190  return;
191  }
192 
193  if (!precordname || precordname[0] == '\0' || !strcmp(precordname, "*")) {
194  precordname = NULL;
195  printf("PVA links in all records\n\n");
196  } else {
197  printf("PVA links in record named '%s'\n\n", precordname);
198  }
199 
200  size_t nchans = 0, nlinks = 0, nconn = 0;
201 
202  pvaGlobal_t::channels_t channels;
203  {
204  Guard G(pvaGlobal->lock);
205  channels = pvaGlobal->channels; // copy snapshot
206  }
207 
208  for(pvaGlobal_t::channels_t::const_iterator it(channels.begin()), end(channels.end());
209  it != end; ++it)
210  {
211  std::tr1::shared_ptr<pvaLinkChannel> chan(it->second.lock());
212  if(!chan) continue;
213 
214  Guard G(chan->lock);
215 
216  if(precordname) {
217  // only show links fields of these records
218  bool match = false;
219  for(pvaLinkChannel::links_t::const_iterator it2(chan->links.begin()), end2(chan->links.end());
220  it2 != end2; ++it2)
221  {
222  const pvaLink *pval = *it2;
223  // plink==NULL shouldn't happen, but we are called for debugging, so be paranoid.
224  if(pval->plink && epicsStrGlobMatch(pval->plink->precord->name, precordname)) {
225  match = true;
226  nlinks++;
227  }
228  }
229  if(!match)
230  continue;
231  }
232 
233  nchans++;
234  if(chan->connected_latched)
235  nconn++;
236 
237  if(!precordname)
238  nlinks += chan->links.size();
239 
240  if(level<=0)
241  continue;
242 
243  if(level>=2 || (!chan->connected_latched && level==1)) {
244  if(chan->key.first.size()<=28) {
245  printf("%28s ", chan->key.first.c_str());
246  } else {
247  printf("%s\t", chan->key.first.c_str());
248  }
249 
250  printf("conn=%c %zu disconnects, %zu type changes",
251  chan->connected_latched?'T':'F',
252  chan->num_disconnect,
253  chan->num_type_change);
254  if(chan->op_put.valid()) {
255  printf(" Put");
256  }
257 
258  if(level>=3) {
259  printf(", provider '%s'", chan->providerName.c_str());
260  }
261  printf("\n");
262  // level 4 reserved for channel/provider details
263 
264  if(level>=5) {
265  for(pvaLinkChannel::links_t::const_iterator it2(chan->links.begin()), end2(chan->links.end());
266  it2 != end2; ++it2)
267  {
268  const pvaLink *pval = *it2;
269 
270  if(!pval->plink)
271  continue;
272  else if(precordname && !epicsStrGlobMatch(pval->plink->precord->name, precordname))
273  continue;
274 
275  const char *fldname = "???";
276  pdbRecordIterator rec(pval->plink->precord);
277  for(bool done = !!dbFirstField(&rec.ent, 0); !done; done = !!dbNextField(&rec.ent, 0))
278  {
279  if(rec.ent.pfield == (void*)pval->plink) {
280  fldname = rec.ent.pflddes->name;
281  break;
282  }
283  }
284 
285  printf("%*s%s.%s", 30, "", pval->plink ? pval->plink->precord->name : "<NULL>", fldname);
286 
287  switch(pval->pp) {
288  case pvaLinkConfig::NPP: printf(" NPP"); break;
289  case pvaLinkConfig::Default: printf(" Def"); break;
290  case pvaLinkConfig::PP: printf(" PP"); break;
291  case pvaLinkConfig::CP: printf(" CP"); break;
292  case pvaLinkConfig::CPP: printf(" CPP"); break;
293  }
294  switch(pval->ms) {
295  case pvaLinkConfig::NMS: printf(" NMS"); break;
296  case pvaLinkConfig::MS: printf(" MS"); break;
297  case pvaLinkConfig::MSI: printf(" MSI"); break;
298  }
299 
300  printf(" Q=%u pipe=%c defer=%c time=%c retry=%c morder=%d\n",
301  unsigned(pval->queueSize),
302  pval->pipeline ? 'T' : 'F',
303  pval->defer ? 'T' : 'F',
304  pval->time ? 'T' : 'F',
305  pval->retry ? 'T' : 'F',
306  pval->monorder);
307  }
308  printf("\n");
309  }
310  }
311  }
312 
313  printf(" %zu/%zu channels connected used by %zu links\n",
314  nconn, nchans, nlinks);
315 
316  } catch(std::exception& e) {
317  fprintf(stderr, "Error: %s\n", e.what());
318  }
319 }
long dbFirstField(DBENTRY *pdbentry, int dctonly)
Definition: dbStaticLib.c:1316
int epicsStrGlobMatch(const char *str, const char *pattern)
Definition: epicsString.c:279
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
long dbNextField(DBENTRY *pdbentry, int dctonly)
Definition: dbStaticLib.c:1323
#define stderr
Definition: epicsStdio.h:32
epicsExportAddress ( jlif  ,
lsetPVA   
)
epicsExportAddress ( int  ,
pvaLinkDebug   
)
epicsExportAddress ( int  ,
pvaLinkNWorkers   
)
epicsExportRegistrar ( installPVAAddLinkHook  )
void testqsrvCleanup ( void  )

Call after testIocShutdownOk() and before testdbCleanup()

1 testdbPrepare();
2 ...
3 testIocInitOk();
4 ...
5 testqsrvShutdownOk();
6 testIocShutdownOk();
7 testqsrvCleanup();
8 testdbCleanup();

Definition at line 158 of file pvalink.cpp.

159 {
160  try {
161  shutdownStep2();
162  }catch(std::exception& e){
163  testAbort("Error initializing pva link handling : %s\n", e.what());
164  }
165 }
void testAbort(const char *fmt,...)
void testqsrvShutdownOk ( void  )

Call before testIocShutdownOk()

1 testdbPrepare();
2 ...
3 testIocInitOk();
4 ...
5 testqsrvShutdownOk();
6 testIocShutdownOk();
7 testqsrvCleanup();
8 testdbCleanup();

Definition at line 149 of file pvalink.cpp.

150 {
151  try {
152  shutdownStep1();
153  }catch(std::exception& e){
154  testAbort("Error while stopping PVA link pool : %s\n", e.what());
155  }
156 }
void testAbort(const char *fmt,...)
void testqsrvWaitForLinkEvent ( struct link plink)

Definition at line 167 of file pvalink.cpp.

168 {
169  std::tr1::shared_ptr<pvaLinkChannel> lchan;
170  {
171  DBScanLocker lock(plink->precord);
172 
173  if(plink->type!=JSON_LINK || !plink->value.json.jlink || plink->value.json.jlink->pif!=&lsetPVA) {
174  testAbort("Not a PVA link");
175  }
176  pvaLink *pval = static_cast<pvaLink*>(plink->value.json.jlink);
177  lchan = pval->lchan;
178  }
179  if(lchan) {
180  lchan->run_done.wait();
181  }
182 }
epicsMutexId lock
Definition: osiClockTime.c:37
void testAbort(const char *fmt,...)
struct json_link json
Definition: link.h:177

Variable Documentation

int pvaLinkDebug

Definition at line 36 of file pvalink.cpp.

int pvaLinkIsolate

Definition at line 37 of file pvalink.cpp.