Changed dbServerStats() to count the server layers called

This commit is contained in:
Andrew Johnson
2025-02-26 13:29:08 -06:00
parent 72f3e75c8d
commit 350570134e
3 changed files with 41 additions and 40 deletions

View File

@ -130,37 +130,26 @@ int dbServerClient(char *pBuf, size_t bufSize)
int dbServerStats(const char *name, unsigned *channels, unsigned *clients) int dbServerStats(const char *name, unsigned *channels, unsigned *clients)
{ {
dbServer *psrv = (dbServer *)ellFirst(&serverList); dbServer *psrv = (dbServer *)ellFirst(&serverList);
unsigned tch, tcl;
if (state != running || !psrv) if (state != running || !psrv)
return -1; return -1;
for (tch = 0, tcl = 0; psrv; unsigned tch = 0, tcl = 0, nmatch = 0;
psrv = (dbServer *)ellNext(&psrv->node)) { for (; psrv; psrv = (dbServer *)ellNext(&psrv->node)) {
if (!name) { if (psrv->stats &&
if (psrv->stats) { (!name || strcmp(name, psrv->name) == 0)) {
unsigned lch, lcl; unsigned lch = 0, lcl = 0;
psrv->stats(&lch, &lcl); psrv->stats(&lch, &lcl);
tch += lch; tch += lch;
tcl += lcl; tcl += lcl;
} nmatch++;
continue; if (name)
} break; /* No duplicate names in serverList */
if (strcmp(name, psrv->name) == 0) {
if (!psrv->stats)
return -1;
psrv->stats(channels, clients);
return 0;
} }
} }
if (!name) { if (channels) *channels = tch;
if (channels) *channels = tch; if (clients) *clients = tcl;
if (clients) *clients = tcl; return nmatch;
return 0;
}
return -1;
} }
#define STARTSTOP(routine, method, newState) \ #define STARTSTOP(routine, method, newState) \

View File

@ -56,8 +56,8 @@ typedef struct dbServer {
/** @brief Get number of channels and clients currently connected. /** @brief Get number of channels and clients currently connected.
* *
* @param channels NULL or pointer for returning channel count. * @param channels @c NULL or pointer for returning channel count.
* @param clients NULL or pointer for returning client count. * @param clients @c NULL or pointer for returning client count.
*/ */
void (* stats) (unsigned *channels, unsigned *clients); void (* stats) (unsigned *channels, unsigned *clients);
@ -147,21 +147,24 @@ DBCORE_API int dbServerClient(char *pBuf, size_t bufSize);
*/ */
#define HAS_DBSERVER_STATS #define HAS_DBSERVER_STATS
/** @brief Fetch statistics from named server. /** @brief Fetch statistics from server layers.
* *
* This is an API for iocStats and similar to fetch the number of channels * This is an API for iocStats and similar to fetch the number of channels
* and clients connected to the named server layer. * and clients connected to the registered server layers.
* If the name given is NULL the statistics returned are the totals for * If the name given is NULL the statistics returned are the totals from
* all the registered server layers. * all registered server layers, otherwise just from the named server.
* @param name Server name * @param name Server name
* @param channels NULL, or where to return the channel count * @param channels NULL, or where to return the channel count
* @param clients NULL or where to return the client count * @param clients NULL or where to return the client count
* @returns 0 on success; -1 if IOC isn't running, no such named server, * @returns -1 if the IOC isn't running or no servers are registered, without
* or that server doesn't implement the stats method. * writing to the statistics variables. Otherwise it writes to the statistics
* variables and returns the number of dbServer::stats() methods called,
* 0 if a named server wasn't found or doesn't have a stats() method.
* *
* @since UNRELEASED * @since UNRELEASED
*/ */
DBCORE_API int dbServerStats(const char *name, unsigned *channels, unsigned *clients); DBCORE_API int dbServerStats(const char *name, unsigned *channels,
unsigned *clients);
/** @brief Initialize all registered servers. /** @brief Initialize all registered servers.
* *

View File

@ -132,7 +132,7 @@ MAIN(dbServerTest)
int status; int status;
unsigned ch=0, cl=0; unsigned ch=0, cl=0;
testPlan(32); testPlan(35);
/* Prove that we handle substring names properly */ /* Prove that we handle substring names properly */
epicsEnvSet("EPICS_IOC_IGNORE_SERVERS", "none ones"); epicsEnvSet("EPICS_IOC_IGNORE_SERVERS", "none ones");
@ -154,6 +154,9 @@ MAIN(dbServerTest)
testDiag("Registering dbServer 'disabled'"); testDiag("Registering dbServer 'disabled'");
testOk(dbRegisterServer(&disabled) == 0, "Registration accepted"); testOk(dbRegisterServer(&disabled) == 0, "Registration accepted");
testOk(dbServerStats("one", &ch, &cl) == -1 && oneState == NOTHING_CALLED,
"dbServerStats returns error before IOC running");
testDiag("Changing server state"); testDiag("Changing server state");
dbInitServers(); dbInitServers();
testOk(oneState == INIT_CALLED, "dbInitServers"); testOk(oneState == INIT_CALLED, "dbInitServers");
@ -169,16 +172,19 @@ MAIN(dbServerTest)
testOk(oneState == REPORT_CALLED, "dbsr called one::report()"); testOk(oneState == REPORT_CALLED, "dbsr called one::report()");
testDiag("Checking stats functionality"); testDiag("Checking stats functionality");
testOk(dbServerStats("none", &ch, &cl) != 0, "Stats: unknown name rejected"); testOk(dbServerStats("none", &ch, &cl) == 0, "Stats: unknown name ignored");
testOk(dbServerStats("no-routines", &ch, &cl) != 0, "Stats: no-routine rejected"); testOk(dbServerStats("one", &ch, &cl) == 1 && oneState == STATS_CALLED,
testOk(dbServerStats("one", &ch, &cl) == 0 && oneState == STATS_CALLED,
"dbServerStats('one') called one::stats()"); "dbServerStats('one') called one::stats()");
testOk(ch == 2 && cl == 1, "Stats: ch==%d, cl==%d (expected 2, 1)", ch, cl); testOk(ch == 2 && cl == 1, "Stats: ch==%d, cl==%d (expected 2, 1)", ch, cl);
testOk(dbServerStats("no-routines", &ch, &cl) == 0,
"dbServerStats('no-routines') layer not counted");
testOk(ch == 0 && cl == 0, "Stats: ch==%d, cl==%d (expected 0, 0)", ch, cl);
ch = 10; cl = 10; oneState = NOTHING_CALLED; ch = 10; cl = 10; oneState = NOTHING_CALLED;
testOk(dbServerStats(NULL, NULL, &cl) == 0 && oneState == STATS_CALLED, testOk(dbServerStats(NULL, NULL, &cl) == 1 && oneState == STATS_CALLED,
"dbServerStats(NULL, &cl) called one::stats()"); "dbServerStats(NULL, &cl) called one::stats()");
testOk(dbServerStats(NULL, &ch, NULL) == 0 && oneState == STATS_CALLED, testOk(dbServerStats(NULL, &ch, NULL) == 1 && oneState == STATS_CALLED,
"dbServerStats(NULL, &ch) called one::stats()"); "dbServerStats(NULL, &ch) called one::stats()");
testOk(ch == 2 && cl == 1, "Stats: ch==%d, cl==%d (expected 2, 1)", ch, cl); testOk(ch == 2 && cl == 1, "Stats: ch==%d, cl==%d (expected 2, 1)", ch, cl);
@ -206,6 +212,9 @@ MAIN(dbServerTest)
status = dbServerClient(name, sizeof(name)); status = dbServerClient(name, sizeof(name));
testOk(oneState != CLIENT_CALLED_KNOWN, "No call to client() when paused"); testOk(oneState != CLIENT_CALLED_KNOWN, "No call to client() when paused");
testOk(dbServerStats("one", &ch, &cl) == -1 && oneState != STATS_CALLED,
"No call to stats() when paused");
dbStopServers(); dbStopServers();
testOk(oneState == STOP_CALLED, "dbStopServers"); testOk(oneState == STOP_CALLED, "dbStopServers");
testOk(dbUnregisterServer(&toolate) != 0, "No unreg' if not reg'ed"); testOk(dbUnregisterServer(&toolate) != 0, "No unreg' if not reg'ed");