Skip to content

Commit

Permalink
Merge 6379fa3 into cb15717
Browse files Browse the repository at this point in the history
  • Loading branch information
mdavidsaver committed Apr 15, 2024
2 parents cb15717 + 6379fa3 commit 7ef3919
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 21 deletions.
4 changes: 2 additions & 2 deletions modules/database/src/ioc/rsrv/camessage.c
Expand Up @@ -88,7 +88,7 @@ typedef struct rsrv_put_notify {
long nRequest;
short dbrType;
/* end arguments for db_put_field */
void * asWritePvt;
asTrapWrite * asWritePvt;
unsigned valueSize; /* size of block pointed to by pbuffer */
char busy; /* put notify in progress */
char onExtraLaborQueue;
Expand Down Expand Up @@ -756,7 +756,7 @@ static int write_action ( caHdrLargeArray *mp,
struct channel_in_use *pciu;
int status;
long dbStatus;
void *asWritePvt;
asTrapWrite *asWritePvt;

pciu = MPTOPCIU(mp);
if(!pciu){
Expand Down
16 changes: 13 additions & 3 deletions modules/libcom/src/as/asLib.h
Expand Up @@ -22,6 +22,8 @@
extern "C" {
#endif

struct dbChannel;

/* 0 - Use (unverified) client provided host name string.
* 1 - Use actual client IP address. HAG() are resolved to IPs at ACF load time.
*/
Expand Down Expand Up @@ -120,11 +122,19 @@ LIBCOM_API int epicsStdCall asDumpMemFP(FILE *fp,const char *asgname,
LIBCOM_API int epicsStdCall asDumpHash(void);
LIBCOM_API int epicsStdCall asDumpHashFP(FILE *fp);

LIBCOM_API void * epicsStdCall asTrapWriteBeforeWithData(
const char *userid, const char *hostid, void *addr,
/** \brief Handle for in progress asTrapWrite
*
* Returned by asTrapWriteBeforeWithData(), must be passed to asTrapWriteAfterWrite()
*
* \since UNRELEASED Previously was void
*/
typedef struct asTrapWrite asTrapWrite;

LIBCOM_API struct asTrapWrite * epicsStdCall asTrapWriteBeforeWithData(
const char *userid, const char *hostid, struct dbChannel *addr,
int dbrType, int no_elements, void *data);

LIBCOM_API void epicsStdCall asTrapWriteAfterWrite(void *pvt);
LIBCOM_API void epicsStdCall asTrapWriteAfterWrite(struct asTrapWrite *pvt);

#define S_asLib_clientsExist (M_asLib| 1) /*Client Exists*/
#define S_asLib_noUag (M_asLib| 2) /*User Access Group does not exist*/
Expand Down
55 changes: 42 additions & 13 deletions modules/libcom/src/as/asTrapWrite.c
Expand Up @@ -23,6 +23,7 @@
#include "ellLib.h"
#include "freeList.h"
#include "epicsStdio.h"
#include "epicsThread.h"
#include "cantProceed.h"
#include "epicsMutex.h"
#include "ellLib.h"
Expand All @@ -32,16 +33,18 @@

typedef struct listenerPvt {
ELLNODE node;
struct listener *plistener;
struct asTrapListener *plistener;
void *userPvt;
}listenerPvt;

typedef struct listener{
typedef struct asTrapListener{
ELLNODE node;
asTrapWriteListener func;
asTrapWriteListener2 func2;
void *pvt2;
}listener;

typedef struct writeMessage {
typedef struct asTrapWrite {
ELLNODE node;
asTrapWriteMessage message;
ELLLIST listenerPvtList;
Expand All @@ -57,9 +60,10 @@ typedef struct asTrapWritePvt
epicsMutexId lock;
}asTrapWritePvt;

static epicsThreadOnceId asTrapWriteOnce = EPICS_THREAD_ONCE_INIT;
static asTrapWritePvt *pasTrapWritePvt = 0;

static void asTrapWriteInit(void)
static void asTrapWriteInit(void *unused)
{
pasTrapWritePvt = callocMustSucceed(1,sizeof(asTrapWritePvt),"asTrapWriteInit");
ellInit(&pasTrapWritePvt->listenerList);
Expand All @@ -71,19 +75,36 @@ static void asTrapWriteInit(void)
pasTrapWritePvt->lock = epicsMutexMustCreate();
}

asTrapWriteId epicsStdCall asTrapWriteRegisterListener(
asTrapWriteListener func)
static
asTrapWriteId asTrapWriteRegisterInternal(
asTrapWriteListener func,
asTrapWriteListener2 func2,
void *pvt2)
{
listener *plistener;
if(pasTrapWritePvt==0) asTrapWriteInit();
epicsThreadOnce(&asTrapWriteOnce, &asTrapWriteInit, NULL);
plistener = callocMustSucceed(1,sizeof(listener),"asTrapWriteRegisterListener");
plistener->func = func;
plistener->func2 = func2;
plistener->pvt2 = pvt2;
epicsMutexMustLock(pasTrapWritePvt->lock);
ellAdd(&pasTrapWritePvt->listenerList,&plistener->node);
epicsMutexUnlock(pasTrapWritePvt->lock);
return((asTrapWriteId)plistener);
}

asTrapWriteId epicsStdCall asTrapWriteRegisterListener(
asTrapWriteListener func)
{
return asTrapWriteRegisterInternal(func, NULL, NULL);
}

asTrapWriteId epicsStdCall asTrapWriteRegisterListener2(
asTrapWriteListener2 func, void *pvt)
{
return asTrapWriteRegisterInternal(NULL, func, pvt);
}

void epicsStdCall asTrapWriteUnregisterListener(asTrapWriteId id)
{
listener *plistener = (listener *)id;
Expand Down Expand Up @@ -111,8 +132,17 @@ void epicsStdCall asTrapWriteUnregisterListener(asTrapWriteId id)
epicsMutexUnlock(pasTrapWritePvt->lock);
}

void * epicsStdCall asTrapWriteBeforeWithData(
const char *userid, const char *hostid, void *addr,
static
void asTrapCallListener(const listener *plistener, asTrapWriteMessage* msg, int after)
{
if(plistener->func)
(*plistener->func)(msg, after);
else if(plistener->func2)
(*plistener->func2)(plistener->pvt2, msg, after);
}

struct asTrapWrite * epicsStdCall asTrapWriteBeforeWithData(
const char *userid, const char *hostid, struct dbChannel *addr,
int dbrType, int no_elements, void *data)
{
writeMessage *pwriteMessage;
Expand Down Expand Up @@ -140,7 +170,7 @@ void * epicsStdCall asTrapWriteBeforeWithData(

plistenerPvt->plistener = plistener;
pwriteMessage->message.userPvt = 0;
plistener->func(&pwriteMessage->message, 0);
asTrapCallListener(plistener, &pwriteMessage->message, 0);
plistenerPvt->userPvt = pwriteMessage->message.userPvt;
ellAdd(&pwriteMessage->listenerPvtList, &plistenerPvt->node);
plistener = (listener *)ellNext(&plistener->node);
Expand All @@ -149,9 +179,8 @@ void * epicsStdCall asTrapWriteBeforeWithData(
return pwriteMessage;
}

void epicsStdCall asTrapWriteAfterWrite(void *pvt)
void epicsStdCall asTrapWriteAfterWrite(writeMessage *pwriteMessage)
{
writeMessage *pwriteMessage = (writeMessage *)pvt;
listenerPvt *plistenerPvt;

if (pwriteMessage == 0 ||
Expand All @@ -164,7 +193,7 @@ void epicsStdCall asTrapWriteAfterWrite(void *pvt)
listener *plistener = plistenerPvt->plistener;

pwriteMessage->message.userPvt = plistenerPvt->userPvt;
plistener->func(&pwriteMessage->message, 1);
asTrapCallListener(plistener, &pwriteMessage->message, 1);
ellDelete(&pwriteMessage->listenerPvtList, &plistenerPvt->node);
freeListFree(pasTrapWritePvt->freeListListenerPvt, plistenerPvt);
plistenerPvt = pnext;
Expand Down
22 changes: 19 additions & 3 deletions modules/libcom/src/as/asTrapWrite.h
Expand Up @@ -26,6 +26,8 @@
extern "C" {
#endif

struct dbChannel;

/**
* \brief The message passed to registered listeners.
*/
Expand All @@ -38,8 +40,13 @@ typedef struct asTrapWriteMessage {
* server is forwarding the put requests. This pointer holds
* the value the server provides to asTrapWriteWithData(), which
* for RSRV is the dbChannel pointer for the target field.
*
* Valid during callback only. Must not be access afterwards.
*
* \since UNRELEASED type changed from void* to dbChannel*
* \since 3.15.0.1 Storage pointed to changed from dbAddr to dbChannel
*/
void *serverSpecific;
struct dbChannel *serverSpecific;
/** \brief A field for use by the \ref asTrapWriteListener.
*
* When the listener is called before the write, this has the
Expand All @@ -50,13 +57,18 @@ typedef struct asTrapWriteMessage {
void *userPvt;
int dbrType; /**< \brief Data type from ca/db_access.h, NOT dbFldTypes.h */
int no_elements; /**< \brief Array length */
void *data; /**< \brief Might be NULL if no data is available */
const void *data; /**< \brief Might be NULL if no data is available */
} asTrapWriteMessage;

/** \brief Type of identifier needed to unregister an listener.
* \since UNRELEASED Added
*/
struct asTrapListener;
/**
* \brief An identifier needed to unregister an listener.
* \since UNRELEASED Changed from void* to asTrapListener*
*/
typedef void *asTrapWriteId;
typedef struct asTrapListener *asTrapWriteId;

/**
* \brief Pointer to a listener function.
Expand All @@ -73,6 +85,7 @@ typedef void *asTrapWriteId;
* or do anything that causes a delay.
*/
typedef void(*asTrapWriteListener)(asTrapWriteMessage *pmessage,int after);
typedef void(*asTrapWriteListener2)(void *pvt, const asTrapWriteMessage *pmessage,int after);

/**
* \brief Register function to be called on asTrapWriteListener.
Expand All @@ -81,6 +94,9 @@ typedef void(*asTrapWriteListener)(asTrapWriteMessage *pmessage,int after);
*/
LIBCOM_API asTrapWriteId epicsStdCall asTrapWriteRegisterListener(
asTrapWriteListener func);

LIBCOM_API asTrapWriteId epicsStdCall asTrapWriteRegisterListener2(
asTrapWriteListener2 func, void *pvt);
/**
* \brief Unregister asTrapWriteListener.
* \param id Listener identifier from asTrapWriteRegisterListener().
Expand Down

0 comments on commit 7ef3919

Please sign in to comment.