Files
sics/taskobj.c
koennecke 86e246416b - Added bridge functions to histmemsec to make it look more like histmem
- Modifed many modules using histmem to work also with histmemsec
- Extended tasker with task names and task groups
- There is a new taskobj which allows to list tasks and to interact with them.
- Task now supports running Tcl functions as tasks
- There is a new experimental sctcomtask module which allows to define communication
  tasks against a scriptcontext. This is a new feature which should facilitate
  writing sequential scripts using asynchronous communication.
- A fix to make spss7 work when there are no switches
- ORION support for single X. TRICS measures crystals hanging down, ORION
  standing up


SKIPPED:
	psi/ease.c
	psi/faverage.c
	psi/jvlprot.c
	psi/make_gen
	psi/pardef.c
	psi/polterwrite.c
	psi/psi.c
	psi/sinq.c
	psi/spss7.c
2012-12-20 11:32:33 +00:00

186 lines
4.8 KiB
C

/**
* This is the SICS interface object to the tasker module
*
* copyright: GPL
*
* Mark Koennecke, December 2012
*/
#include <sics.h>
#include "sicsobj.h"
#include "sicshipadaba.h"
#include "stptok.h"
#include "macro.h"
typedef struct {
char *scriptName;
SConnection *con;
} TclFunc, *pTclFunc;
/*-------------------------------------------------------------------------*/
static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar)
{
pDynString result = NULL;
char buffer[256], *pDes, *pPtr, name[80], time[80],id[80];
pTaskHead it = NULL;
result = CreateDynString(128,128);
if(result == NULL){
SCWrite(pCon,"ERROR: out of memory in ListCmd", eError);
return 0;
}
snprintf(buffer,sizeof(buffer),"%20s %20s %12s",
"Task", "Start_Time", "ID");
DynStringConcat(result,buffer);
DynStringConcatChar(result,'\n');
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
pDes = TaskDescription(it);
if(pDes != NULL){
pPtr = stptok(pDes,name,sizeof(name),":");
pPtr = stptok(pPtr,time,sizeof(name),":");
pPtr = stptok(pPtr,id,sizeof(name),":");
snprintf(buffer,sizeof(buffer),"%20s %20s %12s",
name,time,id);
DynStringConcat(result,buffer);
DynStringConcatChar(result,'\n');
free(pDes);
}
}
SCWrite(pCon,GetCharArray(result),eValue);
DeleteDynString(result);
return 1;
}
/*----------------------------------------------------------------------*/
static int KillCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar)
{
int status;
if(nPar < 1){
SCWrite(pCon,"ERROR: need name of task to stop", eError);
return 0;
}
status = StopTask(pServ->pTasker,par[0]->value.v.text);
if(status == 0) {
SCWrite(pCon,"ERROR: cannot commit suicide!", eError);
return 0;
}
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
static int TclTaskFunction(void *pData)
{
int retVal, status ;
Tcl_Interp *pTcl;
pTclFunc self = (pTclFunc)pData;
assert(self != NULL);
pTcl = InterpGetTcl(pServ->pSics);
assert(pTcl != NULL);
MacroPush(self->con);
status = Tcl_Eval(pTcl, self->scriptName);
MacroPop();
traceSys("task","Executed %s with results %d and %s",self->scriptName, status,
Tcl_GetStringResult(pTcl));
if(status == 0){
retVal = atoi(Tcl_GetStringResult(pTcl));
} else {
return 1;
}
return retVal;
}
/*--------------------------------------------------------------------*/
static void KillTclFunc(void *pData)
{
pTclFunc self = (pTclFunc)pData;
if(self == NULL){
return;
}
if(self->scriptName){
free(self->scriptName);
}
if(self->con) {
SCDeleteConnection(self->con);
}
free(self);
}
/*------------------------------------------------------------------*/
static void TclFuncSignal(void *pData, int iSignal, void *pSigData)
{
int *iInt;
pTclFunc self = NULL;
self = (pTclFunc) pData;
assert(self);
if (iSignal == SICSINT) {
iInt = (int *) pSigData;
SCSetInterrupt(self->con,*iInt);
}
}
/*----------------------------------------------------------------------*/
static int RunCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar)
{
pTclFunc data = NULL;
if(nPar < 1) {
SCWrite(pCon,"ERROR: need the name of a script to run",eError);
return 0;
}
data = malloc(sizeof(TclFunc));
if(data == NULL){
SCWrite(pCon,"ERROR: out of memory in RunCmd",eError);
return 0;
}
memset(data,0,sizeof(TclFunc));
data->con = SCCreateDummyConnection(pServ->pSics);
data->scriptName = strdup(par[0]->value.v.text);
TaskRegisterN(pServ->pTasker,
data->scriptName,
TclTaskFunction,
TclFuncSignal,
KillTclFunc,
data, 0);
traceSys("task","Started task %s",data->scriptName);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pSICSOBJ pNew = NULL;
pHdb cmd = NULL, node;
pNew = SetupSICSOBJ(pCon,pSics,pData,argc,argv);
if(pNew == NULL){
return 0;
}
cmd = AddSICSHdbPar(pNew->objectNode, "ps", usSpy,
MakeSICSFunc(ListCmd));
cmd = AddSICSHdbPar(pNew->objectNode, "kill", usSpy,
MakeSICSFunc(KillCmd));
SetHdbProperty(cmd,"type","command");
SetHdbProperty(cmd,"priv","spy");
node = MakeSICSHdbPar("task",usSpy,MakeHdbText("banana"));
AddHipadabaChild(cmd,node,NULL);
cmd = AddSICSHdbPar(pNew->objectNode, "run", usSpy,
MakeSICSFunc(RunCmd));
SetHdbProperty(cmd,"type","command");
SetHdbProperty(cmd,"priv","spy");
node = MakeSICSHdbPar("script",usSpy,MakeHdbText("banana"));
AddHipadabaChild(cmd,node,NULL);
return 1;
}