Fixed a number pf memory leaks in the EPICS write code
This commit is contained in:
@ -5,7 +5,7 @@
|
||||
*
|
||||
* copyright: see file COPYRIGHT
|
||||
*
|
||||
* Mark Koennecke, October 2014
|
||||
* Mark Koennecke, October - November 2014
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <sics.h>
|
||||
@ -48,7 +48,7 @@ typedef struct {
|
||||
======================================================================================*/
|
||||
static int EpicsTask(void *userData)
|
||||
{
|
||||
WriteMessage mes;
|
||||
pWriteMessage mes;
|
||||
|
||||
/*
|
||||
drive the main EPICS loop for subscriptions
|
||||
@ -59,12 +59,13 @@ static int EpicsTask(void *userData)
|
||||
process possible messages from the writing threads
|
||||
*/
|
||||
if(epicsMessageQueueTryReceive(writeQueue,&mes,sizeof(mes)) > 0){
|
||||
if(mes.pCon == NULL){
|
||||
traceIO("epics",mes.message);
|
||||
if(mes->pCon == NULL){
|
||||
traceIO("epics",mes->message);
|
||||
} else {
|
||||
SCWrite(mes.pCon,mes.message,eError);
|
||||
SCDeleteConnection(mes.pCon);
|
||||
SCWrite(mes->pCon,mes->message,eError);
|
||||
SCDeleteConnection(mes->pCon);
|
||||
}
|
||||
free(mes);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -102,7 +103,7 @@ static int epicsConnectPV(void *message, void *userData)
|
||||
SetHdbProperty(priv->node,"geterror", "Failed to connect to PV");
|
||||
return MPSTOP;
|
||||
}
|
||||
status = ca_pend_io(3.);
|
||||
status = ca_pend_io(0.2);
|
||||
if(status != ECA_NORMAL){
|
||||
SetHdbProperty(priv->node,"geterror", "Timeout connecting to PV");
|
||||
return MPSTOP;
|
||||
@ -273,6 +274,7 @@ static void connectPV(pHdb node, pEpicsPriv priv)
|
||||
strncpy(priv->pvname,par[1]->value.v.text,sizeof(priv->pvname));
|
||||
SetHdbProperty(node,"readpv", par[1]->value.v.text);
|
||||
AppendHipadabaCallback(node,MakeHipadabaCallback(EPICSReadCallback, priv,free));
|
||||
connectPV(node,priv);
|
||||
|
||||
SCSendOK(con);
|
||||
|
||||
@ -283,6 +285,7 @@ static void connectPV(pHdb node, pEpicsPriv priv)
|
||||
question how to propagate error messages. The solution is a EPICS message queue to which
|
||||
writing threads post. The epics task will read this queue and do the actual printing in the
|
||||
SICS main thread. A convention: NULL means to print to trace.
|
||||
|
||||
================================================================================================*/
|
||||
typedef struct {
|
||||
SConnection *pCon;
|
||||
@ -300,10 +303,13 @@ static void writeEpicsMessage(void *target, char *txt)
|
||||
wm->pCon = SCCopyConnection(target);
|
||||
}
|
||||
strncpy(wm->message,txt,sizeof(wm->message));
|
||||
epicsMessageQueueSend(writeQueue,wm,sizeof(WriteMessage));
|
||||
epicsMessageQueueSend(writeQueue,&wm,sizeof(pWriteMessage));
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------*/
|
||||
/*----------------------------------------------------------------------------------------------
|
||||
To my surprise this is never called. May be, when the thread terminates anyway,
|
||||
epics does not know anymore that the callback existed or how to call it.
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
static void epicsEndCallback(struct event_handler_args args)
|
||||
{
|
||||
char message[512];
|
||||
@ -333,7 +339,7 @@ static void EpicsWriteFunc(void *param)
|
||||
writeEpicsMessage(wp->pCon,error);
|
||||
goto cleanup;
|
||||
}
|
||||
status = ca_pend_io(5.);
|
||||
status = ca_pend_io(0.5);
|
||||
if(status != ECA_NORMAL){
|
||||
snprintf(error,sizeof(error),"ERROR: failed to connect EPICS channel for %s", wp->pvName);
|
||||
writeEpicsMessage(wp->pCon,error);
|
||||
@ -368,6 +374,8 @@ static void EpicsWriteFunc(void *param)
|
||||
goto cleanup;
|
||||
}
|
||||
writeEpicsMessage(wp->pCon,"OK");
|
||||
snprintf(error,sizeof(error),"Writing data for PV %s", wp->pvName);
|
||||
writeEpicsMessage(NULL,error);
|
||||
|
||||
ca_pend_io(0);
|
||||
|
||||
@ -376,6 +384,8 @@ static void EpicsWriteFunc(void *param)
|
||||
SCDeleteConnection(wp->pCon);
|
||||
ReleaseHdbValue(&wp->v);
|
||||
free(wp);
|
||||
ca_clear_channel(cid);
|
||||
ca_context_destroy();
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn EPICSWriteCallback(pHdb currentNode,
|
||||
@ -392,12 +402,14 @@ static hdbCallbackReturn EPICSWriteCallback(pHdb currentNode,
|
||||
SCWrite(mm->callData,"ERROR: out of memory in EPICSWriteCallback", eError);
|
||||
return hdbAbort;
|
||||
}
|
||||
par->pCon = SCCopyConnection(mm->callData);
|
||||
if(mm->callData != NULL){
|
||||
par->pCon = SCCopyConnection(mm->callData);
|
||||
}
|
||||
cloneHdbValue(mm->v,&par->v);
|
||||
strncpy(par->pvName,(char *)userData,sizeof(par->pvName));
|
||||
epicsThreadCreate("Write",
|
||||
epicsThreadPriorityHigh,
|
||||
epicsThreadStackMedium,
|
||||
epicsThreadStackSmall,
|
||||
EpicsWriteFunc,
|
||||
par);
|
||||
}
|
||||
@ -461,7 +473,7 @@ int MakeEpicsAdapter(SConnection * con, SicsInterp * sics,
|
||||
|
||||
self = MakeSICSOBJv("epicsadapter", "EpicsAdapter", HIPNONE, usMugger);
|
||||
createEPICSReadPipe();
|
||||
writeQueue = epicsMessageQueueCreate(64,sizeof(WriteMessage));
|
||||
writeQueue = epicsMessageQueueCreate(64,sizeof(pWriteMessage));
|
||||
|
||||
child = AddSICSHdbPar(self->objectNode,
|
||||
"connectread", usMugger, MakeSICSFunc(EpicsConnectRead));
|
||||
|
Reference in New Issue
Block a user