diff --git a/epicsadapter.c b/epicsadapter.c index 990bd9a..56b9f94 100644 --- a/epicsadapter.c +++ b/epicsadapter.c @@ -5,7 +5,7 @@ * * copyright: see file COPYRIGHT * -* Mark Koennecke, October 2014 +* Mark Koennecke, October - November 2014 */ #include #include @@ -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));