asTrap serverSpecific is dbChannel
Save/restore dbAddr::pfield around callbacks to avoid corruption if CB forgets to restore. Need to peak at dbChannel.h during libCom build. So generate dbCoreAPI.h early, and add extra -I to source location when compiling dbTrapWrite.c
This commit is contained in:

committed by
Andrew Johnson

parent
e6a2047bbf
commit
f6cd43b7cc
@ -16,7 +16,7 @@ USR_CPPFLAGS += -DUSE_TYPED_RSET -DUSE_TYPED_DSET
|
|||||||
# Shared library ABI version.
|
# Shared library ABI version.
|
||||||
SHRLIB_VERSION = $(EPICS_DATABASE_MAJOR_VERSION).$(EPICS_DATABASE_MINOR_VERSION).$(EPICS_DATABASE_MAINTENANCE_VERSION)
|
SHRLIB_VERSION = $(EPICS_DATABASE_MAJOR_VERSION).$(EPICS_DATABASE_MINOR_VERSION).$(EPICS_DATABASE_MAINTENANCE_VERSION)
|
||||||
|
|
||||||
API_HEADER = dbCoreAPI.h
|
# dbCoreAPI.h generated earlier during libcom/
|
||||||
dbCore_API = dbCore
|
dbCore_API = dbCore
|
||||||
|
|
||||||
LIBRARY_IOC += dbCore
|
LIBRARY_IOC += dbCore
|
||||||
|
@ -54,6 +54,8 @@ include $(LIBCOM)/yajl/Makefile
|
|||||||
# Generate library API header file
|
# Generate library API header file
|
||||||
API_HEADER = libComAPI.h
|
API_HEADER = libComAPI.h
|
||||||
Com_API = libCom
|
Com_API = libCom
|
||||||
|
# Generate early to allow a sneak peak at dbChannel.h
|
||||||
|
API_HEADER += dbCoreAPI.h
|
||||||
|
|
||||||
# Library to build:
|
# Library to build:
|
||||||
LIBRARY=Com
|
LIBRARY=Com
|
||||||
|
@ -19,4 +19,8 @@ INC += asTrapWrite.h
|
|||||||
Com_SRCS += asLib.c
|
Com_SRCS += asLib.c
|
||||||
Com_SRCS += asTrapWrite.c
|
Com_SRCS += asTrapWrite.c
|
||||||
|
|
||||||
|
# Allow early access to dbChannel.h
|
||||||
|
asTrapWrite_CPPFLAGS = -I$(LIBCOM)/../../database/src/ioc/db
|
||||||
|
|
||||||
|
|
||||||
CLEANS += asLib.c asLib_lex.c
|
CLEANS += asLib.c asLib_lex.c
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct dbChannel;
|
||||||
|
|
||||||
/* 0 - Use (unverified) client provided host name string.
|
/* 0 - Use (unverified) client provided host name string.
|
||||||
* 1 - Use actual client IP address. HAG() are resolved to IPs at ACF load time.
|
* 1 - Use actual client IP address. HAG() are resolved to IPs at ACF load time.
|
||||||
*/
|
*/
|
||||||
@ -121,7 +123,7 @@ LIBCOM_API int epicsStdCall asDumpHash(void);
|
|||||||
LIBCOM_API int epicsStdCall asDumpHashFP(FILE *fp);
|
LIBCOM_API int epicsStdCall asDumpHashFP(FILE *fp);
|
||||||
|
|
||||||
LIBCOM_API void * epicsStdCall asTrapWriteBeforeWithData(
|
LIBCOM_API void * epicsStdCall asTrapWriteBeforeWithData(
|
||||||
const char *userid, const char *hostid, void *addr,
|
const char *userid, const char *hostid, struct dbChannel *addr,
|
||||||
int dbrType, int no_elements, void *data);
|
int dbrType, int no_elements, void *data);
|
||||||
|
|
||||||
LIBCOM_API void epicsStdCall asTrapWriteAfterWrite(void *pvt);
|
LIBCOM_API void epicsStdCall asTrapWriteAfterWrite(void *pvt);
|
||||||
|
@ -22,10 +22,10 @@
|
|||||||
|
|
||||||
#include "ellLib.h"
|
#include "ellLib.h"
|
||||||
#include "freeList.h"
|
#include "freeList.h"
|
||||||
#include "epicsStdio.h"
|
|
||||||
#include "cantProceed.h"
|
#include "cantProceed.h"
|
||||||
#include "epicsMutex.h"
|
#include "epicsMutex.h"
|
||||||
#include "ellLib.h"
|
#include "ellLib.h"
|
||||||
|
#include <dbChannel.h>
|
||||||
|
|
||||||
#include "asLib.h"
|
#include "asLib.h"
|
||||||
#include "asTrapWrite.h"
|
#include "asTrapWrite.h"
|
||||||
@ -112,11 +112,12 @@ void epicsStdCall asTrapWriteUnregisterListener(asTrapWriteId id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void * epicsStdCall asTrapWriteBeforeWithData(
|
void * epicsStdCall asTrapWriteBeforeWithData(
|
||||||
const char *userid, const char *hostid, void *addr,
|
const char *userid, const char *hostid, dbChannel *chan,
|
||||||
int dbrType, int no_elements, void *data)
|
int dbrType, int no_elements, void *data)
|
||||||
{
|
{
|
||||||
writeMessage *pwriteMessage;
|
writeMessage *pwriteMessage;
|
||||||
listener *plistener;
|
listener *plistener;
|
||||||
|
void *pfieldsave;
|
||||||
|
|
||||||
if (pasTrapWritePvt == 0 ||
|
if (pasTrapWritePvt == 0 ||
|
||||||
ellCount(&pasTrapWritePvt->listenerList) <= 0) return 0;
|
ellCount(&pasTrapWritePvt->listenerList) <= 0) return 0;
|
||||||
@ -125,13 +126,14 @@ void * epicsStdCall asTrapWriteBeforeWithData(
|
|||||||
pasTrapWritePvt->freeListWriteMessage);
|
pasTrapWritePvt->freeListWriteMessage);
|
||||||
pwriteMessage->message.userid = userid;
|
pwriteMessage->message.userid = userid;
|
||||||
pwriteMessage->message.hostid = hostid;
|
pwriteMessage->message.hostid = hostid;
|
||||||
pwriteMessage->message.serverSpecific = addr;
|
pwriteMessage->message.serverSpecific = chan;
|
||||||
pwriteMessage->message.dbrType = dbrType;
|
pwriteMessage->message.dbrType = dbrType;
|
||||||
pwriteMessage->message.no_elements = no_elements;
|
pwriteMessage->message.no_elements = no_elements;
|
||||||
pwriteMessage->message.data = data;
|
pwriteMessage->message.data = data;
|
||||||
ellInit(&pwriteMessage->listenerPvtList);
|
ellInit(&pwriteMessage->listenerPvtList);
|
||||||
|
|
||||||
epicsMutexMustLock(pasTrapWritePvt->lock);
|
epicsMutexMustLock(pasTrapWritePvt->lock);
|
||||||
|
pfieldsave = chan->addr.pfield;
|
||||||
ellAdd(&pasTrapWritePvt->writeMessageList, &pwriteMessage->node);
|
ellAdd(&pasTrapWritePvt->writeMessageList, &pwriteMessage->node);
|
||||||
plistener = (listener *)ellFirst(&pasTrapWritePvt->listenerList);
|
plistener = (listener *)ellFirst(&pasTrapWritePvt->listenerList);
|
||||||
while (plistener) {
|
while (plistener) {
|
||||||
@ -141,6 +143,7 @@ void * epicsStdCall asTrapWriteBeforeWithData(
|
|||||||
plistenerPvt->plistener = plistener;
|
plistenerPvt->plistener = plistener;
|
||||||
pwriteMessage->message.userPvt = 0;
|
pwriteMessage->message.userPvt = 0;
|
||||||
plistener->func(&pwriteMessage->message, 0);
|
plistener->func(&pwriteMessage->message, 0);
|
||||||
|
chan->addr.pfield = pfieldsave;
|
||||||
plistenerPvt->userPvt = pwriteMessage->message.userPvt;
|
plistenerPvt->userPvt = pwriteMessage->message.userPvt;
|
||||||
ellAdd(&pwriteMessage->listenerPvtList, &plistenerPvt->node);
|
ellAdd(&pwriteMessage->listenerPvtList, &plistenerPvt->node);
|
||||||
plistener = (listener *)ellNext(&plistener->node);
|
plistener = (listener *)ellNext(&plistener->node);
|
||||||
@ -153,11 +156,15 @@ void epicsStdCall asTrapWriteAfterWrite(void *pvt)
|
|||||||
{
|
{
|
||||||
writeMessage *pwriteMessage = (writeMessage *)pvt;
|
writeMessage *pwriteMessage = (writeMessage *)pvt;
|
||||||
listenerPvt *plistenerPvt;
|
listenerPvt *plistenerPvt;
|
||||||
|
dbChannel *chan;
|
||||||
|
void *pfieldsave;
|
||||||
|
|
||||||
if (pwriteMessage == 0 ||
|
if (pwriteMessage == 0 ||
|
||||||
pasTrapWritePvt == 0) return;
|
pasTrapWritePvt == 0) return;
|
||||||
|
|
||||||
epicsMutexMustLock(pasTrapWritePvt->lock);
|
epicsMutexMustLock(pasTrapWritePvt->lock);
|
||||||
|
chan = pwriteMessage->message.serverSpecific;
|
||||||
|
pfieldsave = chan->addr.pfield;
|
||||||
plistenerPvt = (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList);
|
plistenerPvt = (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList);
|
||||||
while (plistenerPvt) {
|
while (plistenerPvt) {
|
||||||
listenerPvt *pnext = (listenerPvt *)ellNext(&plistenerPvt->node);
|
listenerPvt *pnext = (listenerPvt *)ellNext(&plistenerPvt->node);
|
||||||
@ -165,6 +172,7 @@ void epicsStdCall asTrapWriteAfterWrite(void *pvt)
|
|||||||
|
|
||||||
pwriteMessage->message.userPvt = plistenerPvt->userPvt;
|
pwriteMessage->message.userPvt = plistenerPvt->userPvt;
|
||||||
plistener->func(&pwriteMessage->message, 1);
|
plistener->func(&pwriteMessage->message, 1);
|
||||||
|
chan->addr.pfield = pfieldsave;
|
||||||
ellDelete(&pwriteMessage->listenerPvtList, &plistenerPvt->node);
|
ellDelete(&pwriteMessage->listenerPvtList, &plistenerPvt->node);
|
||||||
freeListFree(pasTrapWritePvt->freeListListenerPvt, plistenerPvt);
|
freeListFree(pasTrapWritePvt->freeListListenerPvt, plistenerPvt);
|
||||||
plistenerPvt = pnext;
|
plistenerPvt = pnext;
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct dbChannel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The message passed to registered listeners.
|
* \brief The message passed to registered listeners.
|
||||||
*/
|
*/
|
||||||
@ -39,7 +41,7 @@ typedef struct asTrapWriteMessage {
|
|||||||
* the value the server provides to asTrapWriteWithData(), which
|
* the value the server provides to asTrapWriteWithData(), which
|
||||||
* for RSRV is the dbChannel pointer for the target field.
|
* for RSRV is the dbChannel pointer for the target field.
|
||||||
*/
|
*/
|
||||||
void *serverSpecific;
|
struct dbChannel *serverSpecific;
|
||||||
/** \brief A field for use by the \ref asTrapWriteListener.
|
/** \brief A field for use by the \ref asTrapWriteListener.
|
||||||
*
|
*
|
||||||
* When the listener is called before the write, this has the
|
* When the listener is called before the write, this has the
|
||||||
|
Reference in New Issue
Block a user