diff --git a/configure/CONFIG_ENV b/configure/CONFIG_ENV
index 1565b2ec9..59e72d883 100644
--- a/configure/CONFIG_ENV
+++ b/configure/CONFIG_ENV
@@ -47,6 +47,9 @@ EPICS_CAS_SERVER_PORT=
EPICS_CAS_INTF_ADDR_LIST=""
EPICS_CAS_IGNORE_ADDR_LIST=""
+# Servers to disable
+EPICS_IOC_IGNORE_SERVERS=""
+
# Log Server:
# EPICS_IOC_LOG_PORT Log server port number etc.
EPICS_IOC_LOG_PORT=7004
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 3a3f0d3be..c8f2bc658 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -3,11 +3,11 @@
- EPICS Base R3.16.1 Release Notes
+ EPICS Base R3.17.0 Release Notes
-EPICS Base Release 3.16.1
+EPICS Base Release 3.17.0
+Extend the dbServer API with init/run/pause/stop methods
+
+This change permits IOCs to be built that omit the CA server (RSRV) by
+removing its registrar entry which is now provided in the new rsrv.dbd
+file. Other server layers can be built into the IOC (alongside RSRV or in place
+of it) by registering them in a similar manner. The dbServer API is documented
+with Doxygen comments in the header file.
+
+Specific IOC server layers can be disabled at runtime by adding their name to
+the environment variable EPICS_IOC_IGNORE_SERVERS (separated by spaces if more
+than one should be ignored).
+
+
+Changes from the 3.16 branch since 3.16.1
+
+
+
+
+
Changes made between 3.16.0.1 and 3.16.1
IOC Database Support for 64-bit integers
diff --git a/src/ioc/db/dbServer.c b/src/ioc/db/dbServer.c
index bc1094ce7..5374f02ad 100644
--- a/src/ioc/db/dbServer.c
+++ b/src/ioc/db/dbServer.c
@@ -10,34 +10,96 @@
*/
#include
+#include
#include "ellLib.h"
+#include "envDefs.h"
#include "epicsStdio.h"
#define epicsExportSharedSymbols
#include "dbServer.h"
static ELLLIST serverList = ELLLIST_INIT;
+static enum { registering, initialized, running, paused, stopped }
+ state = registering;
+static char *stateNames[] = {
+ "registering", "initialized", "running", "paused", "stopped"
+};
-
-void dbRegisterServer(dbServer *psrv)
+int dbRegisterServer(dbServer *psrv)
{
- if (ellNext(&psrv->node)) {
+ const char * ignore = envGetConfigParamPtr(&EPICS_IOC_IGNORE_SERVERS);
+
+ if (!psrv || !psrv->name || state != registering)
+ return -1;
+
+ if (strchr(psrv->name, ' ')) {
+ fprintf(stderr, "dbRegisterServer: Bad server name '%s'\n",
+ psrv->name);
+ return -1;
+ }
+
+ if (ignore) {
+ size_t len = strlen(psrv->name);
+ const char *found;
+ while ((found = strstr(ignore, psrv->name))) {
+ /* Make sure the name isn't just a substring */
+ if ((found == ignore || (found > ignore && found[-1] == ' ')) &&
+ (found[len] == 0 || found[len] == ' ')) {
+ fprintf(stderr, "dbRegisterServer: Ignoring '%s', per environment\n",
+ psrv->name);
+ return 0;
+ }
+ /* It was, try again further down */
+ ignore = found + len;
+ }
+ }
+
+ if (ellNext(&psrv->node) || ellLast(&serverList) == &psrv->node) {
fprintf(stderr, "dbRegisterServer: '%s' registered twice?\n",
psrv->name);
- return;
+ return -1;
}
ellAdd(&serverList, &psrv->node);
+ return 0;
+}
+
+int dbUnregisterServer(dbServer *psrv)
+{
+ if (state != registering && state != stopped) {
+ fprintf(stderr, "dbUnregisterServer: Servers still active!\n");
+ return -1;
+ }
+ if (ellFind(&serverList, &psrv->node) < 0) {
+ fprintf(stderr, "dbUnregisterServer: '%s' not registered.\n",
+ psrv->name);
+ return -1;
+ }
+ if (state == stopped && psrv->stop == NULL) {
+ fprintf(stderr, "dbUnregisterServer: '%s' has no stop() method.\n",
+ psrv->name);
+ return -1;
+ }
+
+ ellDelete(&serverList, &psrv->node);
+ return 0;
}
void dbsr(unsigned level)
{
dbServer *psrv = (dbServer *)ellFirst(&serverList);
+ if (!psrv) {
+ printf("No server layers registered with IOC\n");
+ return;
+ }
+
+ printf("Server state: %s\n", stateNames[state]);
+
while (psrv) {
- printf("Server '%s':\n", psrv->name);
- if (psrv->report)
+ printf("Server '%s'\n", psrv->name);
+ if (state == running && psrv->report)
psrv->report(level);
psrv = (dbServer *)ellNext(&psrv->node);
}
@@ -47,6 +109,9 @@ int dbServerClient(char *pBuf, size_t bufSize)
{
dbServer *psrv = (dbServer *)ellFirst(&serverList);
+ if (state != running)
+ return -1;
+
while (psrv) {
if (psrv->client &&
psrv->client(pBuf, bufSize) == 0)
@@ -56,3 +121,20 @@ int dbServerClient(char *pBuf, size_t bufSize)
return -1;
}
+#define STARTSTOP(routine, method, newState) \
+void routine(void) \
+{ \
+ dbServer *psrv = (dbServer *)ellFirst(&serverList); \
+\
+ while (psrv) { \
+ if (psrv->method) \
+ psrv->method(); \
+ psrv = (dbServer *)ellNext(&psrv->node); \
+ } \
+ state = newState; \
+}
+
+STARTSTOP(dbInitServers, init, initialized)
+STARTSTOP(dbRunServers, run, running)
+STARTSTOP(dbPauseServers, pause, paused)
+STARTSTOP(dbStopServers, stop, stopped)
diff --git a/src/ioc/db/dbServer.h b/src/ioc/db/dbServer.h
index 345468676..ce5244e11 100644
--- a/src/ioc/db/dbServer.h
+++ b/src/ioc/db/dbServer.h
@@ -5,8 +5,20 @@
* in file LICENSE that is included with this distribution.
\*************************************************************************/
-/*
- * Author: Andrew Johnson
+/**
+ * @file dbServer.h
+ * @author Andrew Johnson
+ *
+ * @brief The IOC's interface to the server layers that publish its PVs.
+ *
+ * All server layers which publish IOC record data should initialize a
+ * dbServer structure and register it with the IOC. The methods that
+ * the dbServer interface provides allow the IOC to start, pause and stop
+ * the servers together, and to provide status and debugging information
+ * to the IOC user/developer through a common set of commands.
+ *
+ * @todo No API is provided yet for calling stats() methods.
+ * Nothing in the IOC calls dbStopServers(), not sure where it should go.
*/
#ifndef INC_dbServer_H
@@ -21,36 +33,141 @@
extern "C" {
#endif
-/* Server information structure */
+/** @brief Server information structure.
+ *
+ * Every server layer should initialize and register an instance of this
+ * structure with the IOC by passing it to the dbRegisterServer() routine.
+ *
+ * All methods in this struct are optional; use @c NULL if a server is
+ * unable to support a particular operation (or if it hasn't been
+ * implemented yet).
+ */
typedef struct dbServer {
+ /** @brief Linked list node; initialize to @c ELLNODE_INIT */
ELLNODE node;
+
+ /** @brief A short server identifier; printable, with no spaces */
const char *name;
- /* Print level-dependent status report to stdout */
+ /** @brief Print level-dependent status report to stdout.
+ *
+ * @param level Interest level, specifies how much detail to print.
+ */
void (* report) (unsigned level);
- /* Get number of channels and clients connected */
+ /** @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.
+ */
void (* stats) (unsigned *channels, unsigned *clients);
- /* Get identity of client initiating the calling thread */
- /* Must return 0 (OK), or -1 (ERROR) from unknown threads */
+ /** @brief Get identity of client initiating the calling thread.
+ *
+ * Must fill in the buffer with the client's identity when called from a
+ * thread that belongs to this server layer. For other threads, the
+ * method should do nothing, just return -1.
+ * @param pBuf Buffer for client identity string.
+ * @param bufSize Number of chars available in pBuf.
+ * @return -1 means calling thread is not owned by this server.
+ * 0 means the thread was recognized and pBuf has been filled in.
+ */
int (* client) (char *pBuf, size_t bufSize);
+
+ /** @name Control Methods
+ * These control methods for the server will be called by routines
+ * related to iocInit for all registered servers in turn when the IOC
+ * is being initialized, run, paused and stopped respectively.
+ *
+ * @{
+ */
+
+ /** @brief Server init method.
+ *
+ * Called for all registered servers by dbInitServers().
+ */
+ void (* init) (void);
+
+ /** @brief Server run method.
+ *
+ * Called for all registered servers by dbRunServers().
+ */
+ void (* run) (void);
+
+ /** @brief Server pause method.
+ *
+ * Called for all registered servers by dbPauseServers().
+ */
+ void (* pause) (void);
+
+ /** @brief Server stop method.
+ *
+ * Called for all registered servers by dbStopServers().
+ */
+ void (* stop) (void);
+
+ /** @}
+ */
} dbServer;
-epicsShareFunc void dbRegisterServer(dbServer *psrv);
-
-/* Extra routines could be added if/when needed:
+/** @brief Register a server layer with the IOC
*
- * epicsShareFunc const dbServer* dbFindServer(const char *name);
- * epicsShareFunc void dbIterateServers(srvIterFunc func, void *user);
+ * This should only be called once for each server layer.
+ * @param psrv Server information structure for the server
*/
+epicsShareFunc int dbRegisterServer(dbServer *psrv);
+/** @brief Unregister a server layer
+ *
+ * This should only be called when the servers are inactive.
+ * @param psrv Server information structure for the server
+ */
+epicsShareFunc int dbUnregisterServer(dbServer *psrv);
+
+/** @brief Print dbServer Reports.
+*
+ * Calls the report methods of all registered servers.
+ * This routine is provided as an IOC Shell command.
+ * @param level Interest level, specifies how much detail to print.
+ */
epicsShareFunc void dbsr(unsigned level);
+/** @brief Query servers for client's identity.
+ *
+ * This routine is called by code that wants to identify who (or what)
+ * is responsible for the thread which is currently running. Setting
+ * the @c TPRO field of a record is one way to trigger this; the identity
+ * of the calling thread is printed along with the record name whenever
+ * the record is subsequently processed.
+ */
epicsShareFunc int dbServerClient(char *pBuf, size_t bufSize);
+/** @brief Initialize all registered servers.
+ *
+ * Calls all dbServer::init() methods.
+ */
+epicsShareFunc void dbInitServers(void);
+
+/** @brief Run all registered servers.
+ *
+ * Calls all dbServer::run() methods.
+ */
+epicsShareFunc void dbRunServers(void);
+
+/** @brief Pause all registered servers.
+ *
+ * Calls all dbServer::pause() methods.
+ */
+epicsShareFunc void dbPauseServers(void);
+
+/** @brief Stop all registered servers.
+ *
+ * Calls all dbServer::stop() methods.
+ */
+epicsShareFunc void dbStopServers(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/ioc/db/test/Makefile b/src/ioc/db/test/Makefile
index 37ec3da74..ff464f02a 100644
--- a/src/ioc/db/test/Makefile
+++ b/src/ioc/db/test/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
-# in the file LICENSE that is included with this distribution.
+# in the file LICENSE that is included with this distribution.
#*************************************************************************
TOP=../../../..
@@ -94,6 +94,11 @@ dbStateTest_SRCS += dbStateTest.c
testHarness_SRCS += dbStateTest.c
TESTS += dbStateTest
+TESTPROD_HOST += dbServerTest
+dbServerTest_SRCS += dbServerTest.c
+testHarness_SRCS += dbServerTest.c
+TESTS += dbServerTest
+
TESTPROD_HOST += dbCaStatsTest
dbCaStatsTest_SRCS += dbCaStatsTest.c
dbCaStatsTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp
@@ -192,4 +197,3 @@ dbStressLock$(DEP): $(COMMON_DIR)/xRecord.h
devx$(DEP): $(COMMON_DIR)/xRecord.h
scanIoTest$(DEP): $(COMMON_DIR)/xRecord.h
xRecord$(DEP): $(COMMON_DIR)/xRecord.h
-
diff --git a/src/ioc/db/test/dbServerTest.c b/src/ioc/db/test/dbServerTest.c
new file mode 100644
index 000000000..f0d5bf6ac
--- /dev/null
+++ b/src/ioc/db/test/dbServerTest.c
@@ -0,0 +1,190 @@
+/*************************************************************************\
+* Copyright (c) 2017 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+ \*************************************************************************/
+
+/*
+ * Author: Andrew Johnson
+ */
+
+#include
+
+#include "dbServer.h"
+
+#include
+#include
+#include
+
+enum {
+ NOTHING_CALLED,
+ REPORT_CALLED,
+ CLIENT_CALLED_UNKNOWN,
+ CLIENT_CALLED_KNOWN,
+ STATS_CALLED,
+ INIT_CALLED,
+ RUN_CALLED,
+ PAUSE_CALLED,
+ STOP_CALLED
+} oneState;
+
+char *oneSim;
+
+void oneReport(unsigned level)
+{
+ oneState = REPORT_CALLED;
+}
+
+void oneStats(unsigned *channels, unsigned *clients)
+{
+ oneState = STATS_CALLED;
+}
+
+int oneClient(char *pbuf, size_t len)
+{
+ if (oneSim) {
+ strncpy(pbuf, oneSim, len);
+ oneState = CLIENT_CALLED_KNOWN;
+ oneSim = NULL;
+ return 0;
+ }
+ oneState = CLIENT_CALLED_UNKNOWN;
+ return -1;
+}
+
+void oneInit(void)
+{
+ oneState = INIT_CALLED;
+}
+
+void oneRun(void)
+{
+ oneState = RUN_CALLED;
+}
+
+void onePause(void)
+{
+ oneState = PAUSE_CALLED;
+}
+
+void oneStop(void)
+{
+ oneState = STOP_CALLED;
+}
+
+dbServer one = {
+ ELLNODE_INIT, "one",
+ oneReport, oneStats, oneClient,
+ oneInit, oneRun, onePause, oneStop
+};
+
+
+/* Server layer for testing NULL methods */
+
+dbServer no_routines = {
+ ELLNODE_INIT, "no-routines",
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL
+};
+
+
+/* Server layer which should be disabled */
+
+int disInitialized = 0;
+
+void disInit(void)
+{
+ disInitialized = 1;
+}
+
+dbServer disabled = {
+ ELLNODE_INIT, "disabled",
+ NULL, NULL, NULL,
+ disInit, NULL, NULL, NULL
+};
+
+dbServer illegal = {
+ ELLNODE_INIT, "bad name",
+ NULL, NULL, NULL,
+ disInit, NULL, NULL, NULL
+};
+
+dbServer toolate = {
+ ELLNODE_INIT, "toolate",
+ NULL, NULL, NULL,
+ disInit, NULL, NULL, NULL
+};
+
+
+MAIN(dbServerTest)
+{
+ char name[16];
+ char *theName = "The One";
+ int status;
+
+ testPlan(24);
+
+ /* Prove that we handle substring names properly */
+ epicsEnvSet("EPICS_IOC_IGNORE_SERVERS", "none ones");
+
+ testDiag("Registering dbServer 'one'");
+ testOk(dbRegisterServer(&one) == 0, "Registered 'one'");
+ testOk1(oneState == NOTHING_CALLED);
+
+ testOk(dbRegisterServer(&one) != 0, "Duplicate registration rejected");
+ testOk(dbRegisterServer(&illegal) != 0, "Illegal registration rejected");
+
+ testDiag("Registering dbServer 'no-routines'");
+ testOk(dbRegisterServer(&no_routines) == 0, "Registered 'no-routines'");
+ testOk(dbUnregisterServer(&no_routines) == 0, "'no-routines' unreg'd");
+ testOk(dbRegisterServer(&no_routines) == 0, "Re-registered 'no-routines'");
+
+ epicsEnvSet("EPICS_IOC_IGNORE_SERVERS", "disabled nonexistent");
+ testDiag("Registering dbServer 'disabled'");
+ testOk(dbRegisterServer(&disabled) == 0, "Registration accepted");
+
+ testDiag("Changing server state");
+ dbInitServers();
+ testOk(oneState == INIT_CALLED, "dbInitServers");
+ testOk(disInitialized == 0, "Disabled server not initialized");
+ testOk(dbRegisterServer(&toolate) != 0, "No registration while active");
+
+ dbRunServers();
+ testOk(oneState == RUN_CALLED, "dbRunServers");
+ testOk(dbUnregisterServer(&one) != 0, "No unregistration while active");
+
+ testDiag("Checking server methods called");
+ dbsr(0);
+ testOk(oneState == REPORT_CALLED, "dbsr called report()");
+
+ oneSim = NULL;
+ name[0] = 0;
+ status = dbServerClient(name, sizeof(name));
+ testOk(oneState == CLIENT_CALLED_UNKNOWN, "Client unknown");
+ testOk(status == -1 && name[0] == 0,
+ "dbServerClient mismatch");
+
+ oneSim = theName;
+ name[0] = 0;
+ status = dbServerClient(name, sizeof(name));
+ testOk(oneState == CLIENT_CALLED_KNOWN, "Client known");
+ testOk(status == 0 && strcmp(name, theName) == 0,
+ "dbServerClient match");
+
+ dbPauseServers();
+ testOk(oneState == PAUSE_CALLED, "dbPauseServers");
+
+ dbsr(0);
+ testOk(oneState != REPORT_CALLED, "No call to report() when paused");
+
+ status = dbServerClient(name, sizeof(name));
+ testOk(oneState != CLIENT_CALLED_KNOWN, "No call to client() when paused");
+
+ dbStopServers();
+ testOk(oneState == STOP_CALLED, "dbStopServers");
+ testOk(dbUnregisterServer(&toolate) != 0, "No unreg' if not reg'ed");
+ testOk(dbUnregisterServer(&no_routines) != 0, "No unreg' of 'no-routines'");
+
+ return testDone();
+}
diff --git a/src/ioc/db/test/epicsRunDbTests.c b/src/ioc/db/test/epicsRunDbTests.c
index 69f6b082e..4036268fa 100644
--- a/src/ioc/db/test/epicsRunDbTests.c
+++ b/src/ioc/db/test/epicsRunDbTests.c
@@ -20,6 +20,7 @@ int testdbConvert(void);
int callbackTest(void);
int callbackParallelTest(void);
int dbStateTest(void);
+int dbServerTest(void);
int dbCaStatsTest(void);
int dbShutdownTest(void);
int dbScanTest(void);
@@ -41,6 +42,7 @@ void epicsRunDbTests(void)
runTest(callbackTest);
runTest(callbackParallelTest);
runTest(dbStateTest);
+ runTest(dbServerTest);
runTest(dbCaStatsTest);
runTest(dbShutdownTest);
runTest(dbScanTest);
diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c
index 647157d44..05bf7880e 100644
--- a/src/ioc/misc/iocInit.c
+++ b/src/ioc/misc/iocInit.c
@@ -6,7 +6,7 @@
* Copyright (c) 2013 Helmholtz-Zentrum Berlin
* für Materialien und Energie GmbH.
* EPICS BASE is distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Original Author: Marty Kraimer
@@ -52,6 +52,7 @@
#include "dbLock.h"
#include "dbNotify.h"
#include "dbScan.h"
+#include "dbServer.h"
#include "dbStaticLib.h"
#include "dbStaticPvt.h"
#include "devSup.h"
@@ -68,13 +69,12 @@
#include "registryDriverSupport.h"
#include "registryJLinks.h"
#include "registryRecordType.h"
-#include "rsrv.h"
static enum {
iocVirgin, iocBuilding, iocBuilt, iocRunning, iocPaused, iocStopped
} iocState = iocVirgin;
static enum {
- buildRSRV, buildIsolated
+ buildServers, buildIsolated
} iocBuildMode;
/* define forward references*/
@@ -202,15 +202,14 @@ int iocBuild(void)
status = iocBuild_2();
if (status) return status;
- /* Start CA server threads */
- rsrv_init();
+ dbInitServers();
status = iocBuild_3();
if (dbThreadRealtimeLock)
epicsThreadRealtimeLock();
- if (!status) iocBuildMode = buildRSRV;
+ if (!status) iocBuildMode = buildServers;
return status;
}
@@ -246,8 +245,11 @@ int iocRun(void)
if (iocState == iocBuilt)
initHookAnnounce(initHookAfterInterruptAccept);
- rsrv_run();
- initHookAnnounce(initHookAfterCaServerRunning);
+ if (iocBuildMode == buildServers) {
+ dbRunServers();
+ initHookAnnounce(initHookAfterCaServerRunning);
+ }
+
if (iocState == iocBuilt)
initHookAnnounce(initHookAtEnd);
@@ -267,8 +269,10 @@ int iocPause(void)
}
initHookAnnounce(initHookAtIocPause);
- rsrv_pause();
- initHookAnnounce(initHookAfterCaServerPaused);
+ if (iocBuildMode == buildServers) {
+ dbPauseServers();
+ initHookAnnounce(initHookAfterCaServerPaused);
+ }
dbCaPause();
scanPause();
@@ -420,7 +424,7 @@ static void initRecSup(void)
static void initDevSup(void)
{
dbRecordType *pdbRecordType;
-
+
for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList);
pdbRecordType;
pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) {
@@ -701,27 +705,37 @@ static void doFreeRecord(dbRecordType *pdbRecordType, dbCommon *precord,
int iocShutdown(void)
{
- if (iocState == iocVirgin || iocState == iocStopped) return 0;
+ if (iocState == iocVirgin || iocState == iocStopped)
+ return 0;
+
iterateRecords(doCloseLinks, NULL);
- if (iocBuildMode==buildIsolated) {
+
+ if (iocBuildMode == buildIsolated) {
/* stop and "join" threads */
scanStop();
callbackStop();
}
+ else
+ dbStopServers();
+
dbCaShutdown(); /* must be before dbFreeRecord and dbChannelExit */
- if (iocBuildMode==buildIsolated) {
+
+ if (iocBuildMode == buildIsolated) {
/* free resources */
scanCleanup();
callbackCleanup();
+
iterateRecords(doFreeRecord, NULL);
dbLockCleanupRecords(pdbbase);
+
asShutdown();
dbChannelExit();
dbProcessNotifyExit();
iocshFree();
}
+
iocState = iocStopped;
- iocBuildMode = buildRSRV;
+ iocBuildMode = buildServers;
return 0;
}
diff --git a/src/ioc/misc/iocshRegisterCommon.c b/src/ioc/misc/iocshRegisterCommon.c
index fefa716b9..4f8ce6646 100644
--- a/src/ioc/misc/iocshRegisterCommon.c
+++ b/src/ioc/misc/iocshRegisterCommon.c
@@ -4,7 +4,7 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include "envDefs.h"
@@ -21,7 +21,6 @@
#include "iocshRegisterCommon.h"
#include "miscIocRegister.h"
#include "registryIocRegister.h"
-#include "rsrvIocRegister.h"
#define quote(v) #v
#define str(v) quote(v)
@@ -51,7 +50,6 @@ void iocshRegisterCommon(void)
dbIocRegister();
dbtoolsIocRegister();
asIocRegister();
- rsrvIocRegister();
miscIocRegister();
libComRegister();
}
diff --git a/src/ioc/rsrv/Makefile b/src/ioc/rsrv/Makefile
index ba6ed6bd6..8ad7d01c4 100644
--- a/src/ioc/rsrv/Makefile
+++ b/src/ioc/rsrv/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
-# in file LICENSE that is included with this distribution.
+# in file LICENSE that is included with this distribution.
#*************************************************************************
# This is a Makefile fragment, see src/ioc/Makefile.
@@ -16,7 +16,8 @@ caserverio_INCLUDES = -I$(SRC)/ca/client
camessage_INCLUDES = -I$(SRC)/ca/client
INC += rsrv.h
-INC += rsrvIocRegister.h
+
+DBD += rsrv.dbd
dbCore_SRCS += caserverio.c
dbCore_SRCS += caservertask.c
@@ -25,4 +26,3 @@ dbCore_SRCS += camessage.c
dbCore_SRCS += cast_server.c
dbCore_SRCS += online_notify.c
dbCore_SRCS += rsrvIocRegister.c
-
diff --git a/src/ioc/rsrv/caservertask.c b/src/ioc/rsrv/caservertask.c
index 3a493e7f1..0b7a068a5 100644
--- a/src/ioc/rsrv/caservertask.c
+++ b/src/ioc/rsrv/caservertask.c
@@ -470,18 +470,11 @@ void rsrv_build_addr_lists(void)
}
}
-static dbServer rsrv_server = {
- ELLNODE_INIT,
- "rsrv",
- casr,
- casStatsFetch,
- casClientInitiatingCurrentThread
-};
-
/*
* rsrv_init ()
*/
-int rsrv_init (void)
+static
+void rsrv_init (void)
{
long maxBytesAsALong;
long status;
@@ -500,8 +493,6 @@ int rsrv_init (void)
rsrvCurrentClient = epicsThreadPrivateCreate ();
- dbRegisterServer(&rsrv_server);
-
if ( envGetConfigParamPtr ( &EPICS_CAS_SERVER_PORT ) ) {
ca_server_port = envGetInetPortConfigParam ( &EPICS_CAS_SERVER_PORT,
(unsigned short) CA_SERVER_PORT );
@@ -769,26 +760,22 @@ int rsrv_init (void)
&rsrv_online_notify_task, NULL);
epicsEventMustWait(beacon_startStopEvent);
-
- return RSRV_OK;
}
-int rsrv_run (void)
+static
+void rsrv_run (void)
{
castcp_ctl = ctlRun;
casudp_ctl = ctlRun;
beacon_ctl = ctlRun;
-
- return RSRV_OK;
}
-int rsrv_pause (void)
+static
+void rsrv_pause (void)
{
beacon_ctl = ctlPause;
casudp_ctl = ctlPause;
castcp_ctl = ctlPause;
-
- return RSRV_OK;
}
static unsigned countChanListBytes (
@@ -1552,3 +1539,20 @@ void casStatsFetch ( unsigned *pChanCount, unsigned *pCircuitCount )
}
UNLOCK_CLIENTQ;
}
+
+
+static dbServer rsrv_server = {
+ ELLNODE_INIT,
+ "rsrv",
+ casr,
+ casStatsFetch,
+ casClientInitiatingCurrentThread,
+ rsrv_init,
+ rsrv_run,
+ rsrv_pause
+};
+
+void rsrv_register_server(void)
+{
+ dbRegisterServer(&rsrv_server);
+}
diff --git a/src/ioc/rsrv/rsrv.dbd b/src/ioc/rsrv/rsrv.dbd
new file mode 100644
index 000000000..0c3118f82
--- /dev/null
+++ b/src/ioc/rsrv/rsrv.dbd
@@ -0,0 +1,3 @@
+# This DBD file links the RSRV CA server into the IOC
+
+registrar(rsrvRegistrar)
diff --git a/src/ioc/rsrv/rsrv.h b/src/ioc/rsrv/rsrv.h
index 10947cdf0..cb966df2f 100644
--- a/src/ioc/rsrv/rsrv.h
+++ b/src/ioc/rsrv/rsrv.h
@@ -4,7 +4,7 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
@@ -27,9 +27,7 @@
extern "C" {
#endif
-epicsShareFunc int rsrv_init(void);
-epicsShareFunc int rsrv_run(void);
-epicsShareFunc int rsrv_pause(void);
+epicsShareFunc void rsrv_register_server(void);
epicsShareFunc void casr (unsigned level);
epicsShareFunc int casClientInitiatingCurrentThread (
diff --git a/src/ioc/rsrv/rsrvIocRegister.c b/src/ioc/rsrv/rsrvIocRegister.c
index ccbd792dc..afc0ae85a 100644
--- a/src/ioc/rsrv/rsrvIocRegister.c
+++ b/src/ioc/rsrv/rsrvIocRegister.c
@@ -4,18 +4,16 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include "osiSock.h"
#include "iocsh.h"
-#define epicsExportSharedSymbols
+#include "epicsExport.h"
#include "rsrv.h"
#include "server.h"
-#include "rsrvIocRegister.h"
-#include "epicsExport.h"
/* casr */
static const iocshArg casrArg0 = { "level",iocshArgInt};
@@ -26,9 +24,12 @@ static void casrCallFunc(const iocshArgBuf *args)
casr(args[0].ival);
}
-void rsrvIocRegister(void)
+static
+void rsrvRegistrar(void)
{
+ rsrv_register_server();
iocshRegister(&casrFuncDef,casrCallFunc);
}
epicsExportAddress(int, CASDEBUG);
+epicsExportRegistrar(rsrvRegistrar);
diff --git a/src/ioc/rsrv/rsrvIocRegister.h b/src/ioc/rsrv/rsrvIocRegister.h
deleted file mode 100644
index f4c7e31f1..000000000
--- a/src/ioc/rsrv/rsrvIocRegister.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*************************************************************************\
-* Copyright (c) 2007 The University of Chicago, as Operator of Argonne
-* National Laboratory.
-* Copyright (c) 2002 The Regents of the University of California, as
-* Operator of Los Alamos National Laboratory.
-* EPICS BASE is distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
-\*************************************************************************/
-
-#ifndef INC_rsrvIocRegister_H
-#define INC_rsrvIocRegister_H
-
-#include "shareLib.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-epicsShareFunc void rsrvIocRegister(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* INC_rsrvIocRegister_H */
diff --git a/src/libCom/env/envDefs.h b/src/libCom/env/envDefs.h
index 650f8ee58..13df94733 100644
--- a/src/libCom/env/envDefs.h
+++ b/src/libCom/env/envDefs.h
@@ -65,6 +65,7 @@ epicsShareExtern const ENV_PARAM EPICS_BUILD_OS_CLASS;
epicsShareExtern const ENV_PARAM EPICS_BUILD_TARGET_ARCH;
epicsShareExtern const ENV_PARAM EPICS_TIMEZONE;
epicsShareExtern const ENV_PARAM EPICS_TS_NTP_INET;
+epicsShareExtern const ENV_PARAM EPICS_IOC_IGNORE_SERVERS;
epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_PORT;
epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_INET;
epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_FILE_LIMIT;
diff --git a/src/std/softIoc/base.dbd b/src/std/softIoc/base.dbd
index 58f4884ea..564a83845 100644
--- a/src/std/softIoc/base.dbd
+++ b/src/std/softIoc/base.dbd
@@ -26,3 +26,5 @@ include "asSub.dbd"
# IOC Core variables
include "dbCore.dbd"
+# RSRV server
+include "rsrv.dbd"