From 350570134e9b3e0964efe10e4afe2525acdb007f Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 26 Feb 2025 13:29:08 -0600 Subject: [PATCH] Changed dbServerStats() to count the server layers called --- modules/database/src/ioc/db/dbServer.c | 39 ++++++++------------- modules/database/src/ioc/db/dbServer.h | 21 ++++++----- modules/database/test/ioc/db/dbServerTest.c | 21 +++++++---- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/modules/database/src/ioc/db/dbServer.c b/modules/database/src/ioc/db/dbServer.c index c4e5f55c3..527fb97ca 100644 --- a/modules/database/src/ioc/db/dbServer.c +++ b/modules/database/src/ioc/db/dbServer.c @@ -130,37 +130,26 @@ int dbServerClient(char *pBuf, size_t bufSize) int dbServerStats(const char *name, unsigned *channels, unsigned *clients) { dbServer *psrv = (dbServer *)ellFirst(&serverList); - unsigned tch, tcl; - if (state != running || !psrv) return -1; - for (tch = 0, tcl = 0; psrv; - psrv = (dbServer *)ellNext(&psrv->node)) { - if (!name) { - if (psrv->stats) { - unsigned lch, lcl; + unsigned tch = 0, tcl = 0, nmatch = 0; + for (; psrv; psrv = (dbServer *)ellNext(&psrv->node)) { + if (psrv->stats && + (!name || strcmp(name, psrv->name) == 0)) { + unsigned lch = 0, lcl = 0; - psrv->stats(&lch, &lcl); - tch += lch; - tcl += lcl; - } - continue; - } - if (strcmp(name, psrv->name) == 0) { - if (!psrv->stats) - return -1; - - psrv->stats(channels, clients); - return 0; + psrv->stats(&lch, &lcl); + tch += lch; + tcl += lcl; + nmatch++; + if (name) + break; /* No duplicate names in serverList */ } } - if (!name) { - if (channels) *channels = tch; - if (clients) *clients = tcl; - return 0; - } - return -1; + if (channels) *channels = tch; + if (clients) *clients = tcl; + return nmatch; } #define STARTSTOP(routine, method, newState) \ diff --git a/modules/database/src/ioc/db/dbServer.h b/modules/database/src/ioc/db/dbServer.h index 9b16c3b3d..2083a705a 100644 --- a/modules/database/src/ioc/db/dbServer.h +++ b/modules/database/src/ioc/db/dbServer.h @@ -56,8 +56,8 @@ typedef struct dbServer { /** @brief Get number of channels and clients currently connected. * - * @param channels NULL or pointer for returning channel count. - * @param clients NULL or pointer for returning client count. + * @param channels @c NULL or pointer for returning channel count. + * @param clients @c NULL or pointer for returning client count. */ void (* stats) (unsigned *channels, unsigned *clients); @@ -147,21 +147,24 @@ DBCORE_API int dbServerClient(char *pBuf, size_t bufSize); */ #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 - * and clients connected to the named server layer. - * If the name given is NULL the statistics returned are the totals for - * all the registered server layers. + * and clients connected to the registered server layers. + * If the name given is NULL the statistics returned are the totals from + * all registered server layers, otherwise just from the named server. * @param name Server name * @param channels NULL, or where to return the channel 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, - * or that server doesn't implement the stats method. + * @returns -1 if the IOC isn't running or no servers are registered, without + * 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 */ -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. * diff --git a/modules/database/test/ioc/db/dbServerTest.c b/modules/database/test/ioc/db/dbServerTest.c index 97e547deb..db4ba59d1 100644 --- a/modules/database/test/ioc/db/dbServerTest.c +++ b/modules/database/test/ioc/db/dbServerTest.c @@ -132,7 +132,7 @@ MAIN(dbServerTest) int status; unsigned ch=0, cl=0; - testPlan(32); + testPlan(35); /* Prove that we handle substring names properly */ epicsEnvSet("EPICS_IOC_IGNORE_SERVERS", "none ones"); @@ -154,6 +154,9 @@ MAIN(dbServerTest) testDiag("Registering dbServer 'disabled'"); 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"); dbInitServers(); testOk(oneState == INIT_CALLED, "dbInitServers"); @@ -169,16 +172,19 @@ MAIN(dbServerTest) testOk(oneState == REPORT_CALLED, "dbsr called one::report()"); testDiag("Checking stats functionality"); - testOk(dbServerStats("none", &ch, &cl) != 0, "Stats: unknown name rejected"); - testOk(dbServerStats("no-routines", &ch, &cl) != 0, "Stats: no-routine rejected"); - testOk(dbServerStats("one", &ch, &cl) == 0 && oneState == STATS_CALLED, + testOk(dbServerStats("none", &ch, &cl) == 0, "Stats: unknown name ignored"); + testOk(dbServerStats("one", &ch, &cl) == 1 && oneState == STATS_CALLED, "dbServerStats('one') called one::stats()"); 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; - testOk(dbServerStats(NULL, NULL, &cl) == 0 && oneState == STATS_CALLED, + testOk(dbServerStats(NULL, NULL, &cl) == 1 && oneState == STATS_CALLED, "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()"); 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)); 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(); testOk(oneState == STOP_CALLED, "dbStopServers"); testOk(dbUnregisterServer(&toolate) != 0, "No unreg' if not reg'ed");