- fixed problems deallocation sicsobjects
This commit is contained in:
@ -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); */
|
||||||
|
25
devser.c
25
devser.c
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
2
obdes.c
2
obdes.c
@ -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) {
|
||||||
|
@ -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");
|
||||||
|
@ -84,12 +84,14 @@ static void KillSICSOBJfromNode(void *userData)
|
|||||||
NameClass *nameClass = userData;
|
NameClass *nameClass = userData;
|
||||||
SICSOBJ *sicsobj;
|
SICSOBJ *sicsobj;
|
||||||
|
|
||||||
|
if (pServ->pSics != NULL) {
|
||||||
sicsobj = FindCommandData(pServ->pSics, nameClass->name, nameClass->class);
|
sicsobj = FindCommandData(pServ->pSics, nameClass->name, nameClass->class);
|
||||||
if (sicsobj) {
|
if (sicsobj) {
|
||||||
sicsobj->objectNode = NULL; /* do not call RemoveHdbNodeFromParent in KillSICSOBJ */
|
sicsobj->objectNode = NULL; /* do not call RemoveHdbNodeFromParent in KillSICSOBJ */
|
||||||
sicsobj->pDes->parNode = NULL; /* do not free the node twice in KillSICSOBJ/DeleteDescriptor */
|
sicsobj->pDes->parNode = NULL; /* do not free the node twice in KillSICSOBJ/DeleteDescriptor */
|
||||||
RemoveCommand(pServ->pSics, nameClass->name);
|
RemoveCommand(pServ->pSics, nameClass->name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
free(nameClass->name);
|
free(nameClass->name);
|
||||||
free(nameClass->class);
|
free(nameClass->class);
|
||||||
free(nameClass);
|
free(nameClass);
|
||||||
@ -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
2
task.c
@ -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 */
|
||||||
|
Reference in New Issue
Block a user