- fixed problems deallocation sicsobjects

This commit is contained in:
zolliker
2009-02-25 14:50:00 +00:00
parent 1914d04420
commit 4b82f13ab1
7 changed files with 47 additions and 48 deletions

View File

@ -450,12 +450,11 @@ void DeleteInterp(SicsInterp * self)
if (tail) { if (tail) {
pCurrent = tail; pCurrent = tail;
while (pCurrent) { while (pCurrent) {
/* the line below fixes problems with kill functions pCurrent->pNext = NULL; /* inhibit access to killed commands by FindCommandData */
* traversing the command list
*/
pCurrent->pNext = NULL;
if (pCurrent->KFunc) { if (pCurrent->KFunc) {
pCurrent->KFunc(pCurrent->pData); void *data = pCurrent->pData;
pCurrent->pData = NULL; /* make data unreachable by FindCommandData before killing */
pCurrent->KFunc(data);
} }
if (pCurrent->pName) { if (pCurrent->pName) {
/* printf("Deleting %s\n",pCurrent->pName); */ /* printf("Deleting %s\n",pCurrent->pName); */

View File

@ -27,7 +27,6 @@ struct DevSer {
DevAction *toKill; /* list of actions to be killed */ DevAction *toKill; /* list of actions to be killed */
SchedHeader *headers; SchedHeader *headers;
int steps; int steps;
int stopTask;
}; };
static char *devPrio[NumberOfPRIO] = { static char *devPrio[NumberOfPRIO] = {
@ -58,23 +57,14 @@ static void DevFreeActionList(DevAction * actions)
while (actions != NULL) { while (actions != NULL) {
victim = actions; victim = actions;
actions = victim->next; actions = victim->next;
assert(victim->data != NULL);
if (victim->kill != NULL) if (victim->kill != NULL)
victim->kill(victim->data); victim->kill(victim->data);
victim->data=NULL;
free(victim); free(victim);
} }
} }
static void DevKillTask(void *ds)
{
DevSer *devser = ds;
if (devser->stopTask) {
free(devser);
} else {
devser->stopTask = 1;
}
}
DevAction *DevNextAction(DevSer * devser) DevAction *DevNextAction(DevSer * devser)
{ {
DevPrio prio; DevPrio prio;
@ -130,9 +120,6 @@ int DevQueueTask(void *ds)
if (devser->steps == 0) if (devser->steps == 0)
return 1; return 1;
if (devser->stopTask) {
return 0;
}
/* deferred deallocation of removed actions */ /* deferred deallocation of removed actions */
DevFreeActionList(devser->toKill); DevFreeActionList(devser->toKill);
@ -188,10 +175,9 @@ DevSer *DevMake(SConnection * con, int argc, char *argv[])
devser->killCurrent = 0; devser->killCurrent = 0;
devser->actions = NULL; devser->actions = NULL;
devser->headers = NULL; devser->headers = NULL;
devser->stopTask = 0;
devser->toKill = NULL; devser->toKill = NULL;
devser->steps = -1; /* no debugging by default */ devser->steps = -1; /* no debugging by default */
TaskRegister(pServ->pTasker, DevQueueTask, NULL, DevKillTask, devser, 0); TaskRegister(pServ->pTasker, DevQueueTask, NULL, NULL, devser, 0);
return devser; return devser;
} }
@ -235,11 +221,8 @@ void DevKill(DevSer * devser)
devser->killCurrent = 0; devser->killCurrent = 0;
free(devser->current); free(devser->current);
} }
if (devser->stopTask) { TaskRemove(pServ->pTasker, DevQueueTask, devser);
free(devser); free(devser);
} else {
devser->stopTask = 1;
}
} }
void DevDisconnect(DevSer * devser) void DevDisconnect(DevSer * devser)

View File

@ -113,7 +113,7 @@ void RecurseCallbackChains(pHdb node, pHdbMessage message)
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void DeleteNodeData(pHdb node) void DeleteNodeData(pHdb node)
{ {
pHdb tmp = NULL; pHdb tmp = NULL, next = NULL;
if (node == NULL) { if (node == NULL) {
return; return;
@ -132,8 +132,9 @@ void DeleteNodeData(pHdb node)
while (node->child != NULL) { while (node->child != NULL) {
tmp = node->child; tmp = node->child;
node->child = node->child->next; next = node->child->next;
DeleteNodeData(tmp); DeleteNodeData(tmp);
node->child = next;
} }
free(node); free(node);
} }

View File

@ -84,7 +84,7 @@ void DeleteDescriptor(pObjectDescriptor self)
if (self->pKeys) if (self->pKeys)
IFDeleteOptions(self->pKeys); IFDeleteOptions(self->pKeys);
/* /*
* delate a parameter node only when not linked elsewhere * delete a parameter node only when not linked elsewhere
*/ */
if (self->parNode != NULL) { if (self->parNode != NULL) {
if (self->parNode->mama == NULL) { if (self->parNode->mama == NULL) {

View File

@ -43,6 +43,7 @@ typedef struct SctData {
SctController *controller; SctController *controller;
SConnection *conCtx; SConnection *conCtx;
int answered; int answered;
int inMacro;
Hdb *node; Hdb *node;
} SctData; } SctData;
@ -151,6 +152,7 @@ int SctCommand(SConnection * con, SicsInterp * sics, void *object,
Hdb *cNode = NULL; Hdb *cNode = NULL;
hdbValue v; hdbValue v;
double dtime; double dtime;
int iMacro;
assert(sct == object); assert(sct == object);
if (sct->nodes != NULL) { if (sct->nodes != NULL) {
@ -188,11 +190,14 @@ int SctCommand(SConnection * con, SicsInterp * sics, void *object,
* print * print
*/ */
if (strcmp(argv[1], "print") == 0) { if (strcmp(argv[1], "print") == 0) {
iMacro = con->iMacro;
if (queueData != NULL) { if (queueData != NULL) {
queueData->answered = 1; queueData->answered = 1;
con->iMacro = queueData->inMacro; /* take macro flag stored at set callback */
} }
Arg2Text(argc - 2, argv + 2, value, sizeof value); Arg2Text(argc - 2, argv + 2, value, sizeof value);
SCWrite(con, value, eLog); SCWrite(con, value, eWarning);
con->iMacro = iMacro;
return 1; return 1;
} }
@ -205,7 +210,7 @@ int SctCommand(SConnection * con, SicsInterp * sics, void *object,
} }
/* /*
* time stamping (obsolete ? -> see SctActionHandler: timeKey, timeVal) * time stamping
*/ */
if (strcmp(argv[1], "utime") == 0) { if (strcmp(argv[1], "utime") == 0) {
if (argc < 3) { if (argc < 3) {
@ -334,13 +339,13 @@ static char *SctActionHandler(void *actionData, char *lastReply,
commError = 0; commError = 0;
} }
script = strdup(script); script = strdup(script);
if (!SctCallInContext(con, script, node, data->controller, &result)) { if (!SctCallInContext(con, script, node, controller, &result)) {
snprintf(eprop, sizeof eprop, "error_during_%s", data->name); snprintf(eprop, sizeof eprop, "error_during_%s", data->name);
if (strncmp(result, "ERROR: ", 7) == 0) { if (strncmp(result, "ERROR: ", 7) == 0) {
result += 7; result += 7;
} }
emsg = GetHdbProp(node, eprop); emsg = GetHdbProp(node, eprop);
if (emsg == NULL) { if (emsg == NULL || con != controller->conn) {
GetHdbPath(node, path, sizeof path); GetHdbPath(node, path, sizeof path);
SCPrintf(con, eError, SCPrintf(con, eError,
"ERROR: action <%s> in {%s} node %s:\nERROR: %s", "ERROR: action <%s> in {%s} node %s:\nERROR: %s",
@ -364,6 +369,7 @@ static char *SctActionHandler(void *actionData, char *lastReply,
snprintf(msg, sizeof msg, "%dx {%s} %s", cnt, origScript, result); snprintf(msg, sizeof msg, "%dx {%s} %s", cnt, origScript, result);
SetHdbProperty(node, eprop, msg); SetHdbProperty(node, eprop, msg);
send = NULL; send = NULL;
free(script);
goto finish; goto finish;
} }
state = result; state = result;
@ -384,6 +390,7 @@ static char *SctActionHandler(void *actionData, char *lastReply,
snprintf(timeVal, sizeof timeVal, "%.3f", DoubleTime()); snprintf(timeVal, sizeof timeVal, "%.3f", DoubleTime());
SetHdbProperty(node, timeKey, timeVal); SetHdbProperty(node, timeKey, timeVal);
send = NULL; send = NULL;
free(script);
goto finish; goto finish;
} }
SetProp(node, controller->node, "state", state); SetProp(node, controller->node, "state", state);
@ -568,13 +575,15 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
if (data->conCtx != NULL) { if (data->conCtx != NULL) {
GetHdbPath(node, path, sizeof path); GetHdbPath(node, path, sizeof path);
SCPrintf(data->conCtx, eLog, SCPrintf(data->conCtx, eWarning,
"%s target changed to %s before completion", path, "%s target changed to %s before completion", path,
GetCharArray(text)); GetCharArray(text));
SCDeleteConnection(data->conCtx);
} }
DeleteDynString(text); DeleteDynString(text);
data->conCtx = SCCopyConnection(con); data->conCtx = SCCopyConnection(con);
data->answered = 0; data->answered = 0;
data->inMacro = con->iMacro;
DevQueue(data->controller->devser, data, prio, DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, NULL); SctWriteHandler, SctMatch, NULL);
/* no kill function in DevQueue: data is owned by the node (callback list) */ /* no kill function in DevQueue: data is owned by the node (callback list) */
@ -585,13 +594,11 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
if (mm != NULL) { if (mm != NULL) {
if (queueData != NULL && queueData->conCtx != NULL && !data->answered) { if (queueData != NULL && queueData->conCtx != NULL && !data->answered) {
/* update called from a write action */ /* update called from a write action */
/*
data->answered = 1; data->answered = 1;
GetHdbPath(node, path, sizeof path); GetHdbPath(node, path, sizeof path);
text = formatValue(*(mm->v), node); text = formatValue(*(mm->v), node);
SCPrintf(queueData->conCtx, eWarning, "OK: %s set to: %s", path, GetCharArray(text)); SCPrintf(queueData->conCtx, eWarning, "OK: %s set to: %s", path, GetCharArray(text));
DeleteDynString(text); DeleteDynString(text);
*/
} }
return hdbContinue; return hdbContinue;
} }
@ -1050,9 +1057,14 @@ static hdbCallbackReturn SctDebugCallback(Hdb * node, void *userData,
return hdbContinue; return hdbContinue;
} }
static int SctDeferredFree(void *data) static void SctDeferredFree(void *data)
{ {
free(data); free(data);
return;
}
static int SctDeferredTask(void *data)
{
return 0; return 0;
} }
@ -1069,8 +1081,8 @@ static void SctKillController(void *c)
DevKill(controller->devser); DevKill(controller->devser);
controller->devser = NULL; controller->devser = NULL;
if (pServ->pTasker) { if (pServ->pTasker) {
TaskRegister(pServ->pTasker, SctDeferredFree, NULL, NULL, controller, TaskRegister(pServ->pTasker, SctDeferredTask, NULL, SctDeferredFree,
0); controller, 0);
} else { } else {
free(controller); free(controller);
} }
@ -1124,6 +1136,8 @@ static int SctMakeController(SConnection * con, SicsInterp * sics,
if (!controller->devser) if (!controller->devser)
return 0; return 0;
SetHdbProperty(controller->node, "controllerName", objName);
AddCommand(pServ->pSics, objName, InterInvokeSICSOBJ, KillSICSOBJ, ccmd); AddCommand(pServ->pSics, objName, InterInvokeSICSOBJ, KillSICSOBJ, ccmd);
RegisterSICSOBJKillCmd(ccmd, objName); RegisterSICSOBJKillCmd(ccmd, objName);
SetDescriptorKey(ccmd->pDes, "creationCommand", "0"); SetDescriptorKey(ccmd->pDes, "creationCommand", "0");

View File

@ -84,11 +84,13 @@ static void KillSICSOBJfromNode(void *userData)
NameClass *nameClass = userData; NameClass *nameClass = userData;
SICSOBJ *sicsobj; SICSOBJ *sicsobj;
sicsobj = FindCommandData(pServ->pSics, nameClass->name, nameClass->class); if (pServ->pSics != NULL) {
if (sicsobj) { sicsobj = FindCommandData(pServ->pSics, nameClass->name, nameClass->class);
sicsobj->objectNode = NULL; /* do not call RemoveHdbNodeFromParent in KillSICSOBJ */ if (sicsobj) {
sicsobj->pDes->parNode = NULL; /* do not free the node twice in KillSICSOBJ/DeleteDescriptor */ sicsobj->objectNode = NULL; /* do not call RemoveHdbNodeFromParent in KillSICSOBJ */
RemoveCommand(pServ->pSics, nameClass->name); sicsobj->pDes->parNode = NULL; /* do not free the node twice in KillSICSOBJ/DeleteDescriptor */
RemoveCommand(pServ->pSics, nameClass->name);
}
} }
free(nameClass->name); free(nameClass->name);
free(nameClass->class); free(nameClass->class);
@ -159,7 +161,7 @@ void KillSICSOBJ(void *data)
if (self->KillPrivate != NULL && self->pPrivate != NULL) { if (self->KillPrivate != NULL && self->pPrivate != NULL) {
self->KillPrivate(self->pPrivate); self->KillPrivate(self->pPrivate);
} }
if (self->objectNode != NULL) { if (self->objectNode != NULL && pServ->pTasker != NULL) { /* not on rundown */
RemoveHdbNodeFromParent(self->objectNode, pServ->dummyCon); RemoveHdbNodeFromParent(self->objectNode, pServ->dummyCon);
} }
if (self->pDes != NULL) { if (self->pDes != NULL) {

2
task.c
View File

@ -351,7 +351,7 @@ void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData)
int iRet; int iRet;
pTaskHead pCurrent, pNext; pTaskHead pCurrent, pNext;
assert(self); if (self == NULL) return;
assert(self->iID == TASKERID); assert(self->iID == TASKERID);
pNext = self->pHead->pNext; /* skip dummy task */ pNext = self->pHead->pNext; /* skip dummy task */