Fixed a number pf memory leaks in the EPICS write code

This commit is contained in:
2014-11-18 09:21:47 +01:00
parent c24049766c
commit ac5aee6062

View File

@ -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));