Merged branch 'rsrv-register' into 3.17
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
|
||||
<title>EPICS Base R3.16.1 Release Notes</title>
|
||||
<title>EPICS Base R3.17.0 Release Notes</title>
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
<h1 align="center">EPICS Base Release 3.16.1</h1>
|
||||
<h1 align="center">EPICS Base Release 3.17.0</h1>
|
||||
|
||||
<!-- Insert new items immediately below this template ...
|
||||
|
||||
@@ -17,6 +17,25 @@
|
||||
|
||||
-->
|
||||
|
||||
<h3>Extend the dbServer API with init/run/pause/stop methods</h3>
|
||||
|
||||
<p>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 <tt>rsrv.dbd</tt>
|
||||
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.</p>
|
||||
|
||||
<p>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).</p>
|
||||
|
||||
|
||||
<h2 align="center">Changes from the 3.16 branch since 3.16.1</h2>
|
||||
|
||||
<!-- Insert inherited items immediately below here ... -->
|
||||
|
||||
|
||||
|
||||
<h2 align="center">Changes made between 3.16.0.1 and 3.16.1</h2>
|
||||
|
||||
<h3>IOC Database Support for 64-bit integers</h3>
|
||||
|
||||
@@ -10,34 +10,96 @@
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#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)
|
||||
|
||||
@@ -5,8 +5,20 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author: Andrew Johnson <anj@aps.anl.gov>
|
||||
/**
|
||||
* @file dbServer.h
|
||||
* @author Andrew Johnson <anj@aps.anl.gov>
|
||||
*
|
||||
* @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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
190
src/ioc/db/test/dbServerTest.c
Normal file
190
src/ioc/db/test/dbServerTest.c
Normal file
@@ -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 <anj@aps.anl.gov>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "dbServer.h"
|
||||
|
||||
#include <envDefs.h>
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
3
src/ioc/rsrv/rsrv.dbd
Normal file
3
src/ioc/rsrv/rsrv.dbd
Normal file
@@ -0,0 +1,3 @@
|
||||
# This DBD file links the RSRV CA server into the IOC
|
||||
|
||||
registrar(rsrvRegistrar)
|
||||
@@ -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 (
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
1
src/libCom/env/envDefs.h
vendored
1
src/libCom/env/envDefs.h
vendored
@@ -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;
|
||||
|
||||
@@ -26,3 +26,5 @@ include "asSub.dbd"
|
||||
# IOC Core variables
|
||||
include "dbCore.dbd"
|
||||
|
||||
# RSRV server
|
||||
include "rsrv.dbd"
|
||||
|
||||
Reference in New Issue
Block a user