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