Files
epics-base/modules/database/test/ioc/db/jlinkz.c
Michael Davidsaver e34b6c5c0c Fix spelling in comments
Should be non-functional, except for some error message strings.
2021-08-29 07:27:50 -07:00

260 lines
5.3 KiB
C

/*************************************************************************\
* Copyright (c) 2016 Michael Davidsaver
* SPDX-License-Identifier: EPICS
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <dbAccess.h>
#include <link.h>
#include <alarm.h>
#include <dbJLink.h>
#include <dbDefs.h>
#include <dbConvertFast.h>
#include <epicsMutex.h>
#include <epicsAtomic.h>
#include <epicsUnitTest.h>
#define epicsExportSharedSymbols
#include "jlinkz.h"
#include <epicsExport.h>
int numzalloc;
static
void z_open(struct link *plink)
{
zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base);
if(priv->isopen)
testDiag("lsetZ re-open");
priv->isopen = 1;
testDiag("Open jlinkz %p", priv);
}
static
void z_remove(struct dbLocker *locker, struct link *plink)
{
zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base);
epicsMutexLock(priv->lock);
if(!priv->isopen)
testDiag("lsetZ remove without open");
epicsMutexUnlock(priv->lock);
testDiag("Remove/free jlinkz %p", priv);
epicsAtomicDecrIntT(&numzalloc);
epicsMutexDestroy(priv->lock);
free(priv);
plink->value.json.jlink = NULL; /* paranoia */
}
static
int z_connected(const struct link *plink)
{
return 1; /* TODO: not provided should be connected */
}
static
int z_dbftype(const struct link *plink)
{
return DBF_LONG;
}
static
long z_elements(const struct link *plink, long *nelements)
{
*nelements = 1;
return 0;
}
static
long z_getval(struct link *plink, short dbrType, void *pbuffer,
long *pnRequest)
{
long ret;
long (*pconv)(const epicsInt32 *, void *, const dbAddr *) = dbFastGetConvertRoutine[DBF_LONG][dbrType];
zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base);
if(pnRequest && *pnRequest==0) return 0;
epicsMutexLock(priv->lock);
ret = (*pconv)(&priv->value, pbuffer, NULL);
epicsMutexUnlock(priv->lock);
if(ret==0 && pnRequest) *pnRequest = 1;
return ret;
}
/* TODO: atomically get value and alarm */
static
long z_getalarm(const struct link *plink, epicsEnum16 *status,
epicsEnum16 *severity)
{
zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base);
epicsEnum16 sevr, stat;
epicsMutexLock(priv->lock);
sevr = priv->isset ? 0 : INVALID_ALARM;
stat = priv->isset ? 0 : LINK_ALARM;
epicsMutexUnlock(priv->lock);
if(status) *status = stat;
if(severity) *severity = sevr;
return 0;
}
static
long z_putval(struct link *plink, short dbrType,
const void *pbuffer, long nRequest)
{
long ret;
long (*pconv)(epicsInt32 *, const void *, const dbAddr *);
zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base);
if(INVALID_DB_REQ(dbrType))
return S_db_badDbrtype;
pconv = dbFastPutConvertRoutine[DBF_LONG][dbrType];
if(nRequest==0) return 0;
epicsMutexLock(priv->lock);
ret = (*pconv)(&priv->value, pbuffer, NULL);
epicsMutexUnlock(priv->lock);
return ret;
}
static lset lsetZ = {
0, 0, /* non-const, non-volatile */
&z_open,
&z_remove,
NULL, NULL, NULL, /* load */
&z_connected,
&z_dbftype,
&z_elements,
&z_getval,
NULL, /* control limits */
NULL, /* display limits */
NULL, /* alarm limits */
NULL, /* prec */
NULL, /* units */
&z_getalarm,
NULL, /* time */
&z_putval,
NULL, /* putasync */
NULL, /* forward */
NULL, /* doLocked */
};
static
jlink* z_alloc(short dbfType)
{
zpriv *priv;
priv = calloc(1, sizeof(*priv));
if(!priv) goto fail;
priv->lock = epicsMutexCreate();
if(!priv->lock) goto fail;
epicsAtomicIncrIntT(&numzalloc);
testDiag("Alloc jlinkz %p", priv);
return &priv->base;
fail:
if(priv && priv->lock) epicsMutexDestroy(priv->lock);
free(priv);
return NULL;
}
static
void z_free(jlink *pj)
{
zpriv *priv = CONTAINER(pj, zpriv, base);
if(priv->isopen)
testDiag("lsetZ jlink free after open()");
testDiag("Free jlinkz %p", priv);
epicsAtomicDecrIntT(&numzalloc);
epicsMutexDestroy(priv->lock);
free(priv);
}
static
jlif_result z_int(jlink *pj, long long num)
{
zpriv *priv = CONTAINER(pj, zpriv, base);
priv->value = num;
priv->isset = 1;
return jlif_continue;
}
static
jlif_key_result z_start(jlink *pj)
{
return jlif_key_continue;
}
static
jlif_result z_key(jlink *pj, const char *key, size_t len)
{
zpriv *priv = CONTAINER(pj, zpriv, base);
if(len==4 && strncmp(key,"fail", len)==0) {
testDiag("Found fail key jlinkz %p", priv);
return jlif_stop;
} else {
return jlif_continue;
}
}
static
jlif_result z_end(jlink *pj)
{
return jlif_continue;
}
static
struct lset* z_lset(const jlink *pj)
{
return &lsetZ;
}
static jlif jlifZ = {
"z",
&z_alloc,
&z_free,
NULL, /* null */
NULL, /* bool */
&z_int,
NULL, /* double */
NULL, /* string */
&z_start,
&z_key,
&z_end,
NULL, /* start array */
NULL, /* end array */
NULL, /* end child */
&z_lset,
NULL, /* report */
NULL, /* map child */
NULL /* start child */
};
epicsExportAddress(jlif, jlifZ);