- Adapted indenation to new agreed upon system
- Added support for second generation scriptcontext based counter
This commit is contained in:
847
mccontrol.c
847
mccontrol.c
@ -17,435 +17,466 @@
|
||||
#include "stringdict.h"
|
||||
#include "mccontrol.h"
|
||||
/*========================= life and death ==================================*/
|
||||
static void KillMcStasController(void *pData){
|
||||
pMcStasController self = (pMcStasController)pData;
|
||||
if(self == NULL){
|
||||
return;
|
||||
}
|
||||
if(self->pDes != NULL){
|
||||
DeleteDescriptor(self->pDes);
|
||||
}
|
||||
if(self->scripts != NULL){
|
||||
DeleteStringDict(self->scripts);
|
||||
}
|
||||
free(self);
|
||||
static void KillMcStasController(void *pData)
|
||||
{
|
||||
pMcStasController self = (pMcStasController) pData;
|
||||
if (self == NULL) {
|
||||
return;
|
||||
}
|
||||
if (self->pDes != NULL) {
|
||||
DeleteDescriptor(self->pDes);
|
||||
}
|
||||
if (self->scripts != NULL) {
|
||||
DeleteStringDict(self->scripts);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int McStasControllerFactory(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData, int argc, char *argv[]){
|
||||
pMcStasController pNew = NULL;
|
||||
|
||||
pNew = (pMcStasController)malloc(sizeof(McStasController));
|
||||
if(pNew == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating McStasController",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pNew,0,sizeof(McStasController));
|
||||
|
||||
pNew->pDes = CreateDescriptor("McStasController");
|
||||
pNew->scripts = CreateStringDict();
|
||||
if(pNew->pDes == NULL || pNew->scripts == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating McStasController",
|
||||
eError);
|
||||
free(pNew);
|
||||
return 0;
|
||||
}
|
||||
StringDictAddPair(pNew->scripts,"mcstart","UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts,"mcisrunning","UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts,"mcdump","UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts,"mckill","UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts,"mccopydata","UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts,"mcmonfile","UNDEFINED");
|
||||
pNew->pid = -1;
|
||||
pNew->monitorScale = 1;
|
||||
|
||||
return AddCommand(pSics,"mccontrol",
|
||||
McStasControllerWrapper,
|
||||
KillMcStasController,
|
||||
pNew);
|
||||
}
|
||||
/*====================== interpreter interface ============================*/
|
||||
static int configureController(pMcStasController self, SConnection *pCon,
|
||||
int argc, char *argv[]){
|
||||
char pBueffel[256];
|
||||
|
||||
if(argc < 4){
|
||||
SCWrite(pCon,
|
||||
"ERRROR: insufficient number of arguments to mccontrol configure",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
strtolower(argv[2]);
|
||||
if(strcmp(argv[2],"update") == 0){
|
||||
self->updateIntervall = atoi(argv[3]);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(argv[2],"monitorscale") == 0){
|
||||
self->monitorScale = atof(argv[3]);
|
||||
if(self->monitorScale <= 0){
|
||||
SCWrite(pCon,"ERROR: invalid monitor scale",eError);
|
||||
self->monitorScale = 1;
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
if(!StringDictExists(self->scripts,argv[2])){
|
||||
snprintf(pBueffel,255,"ERROR: scriptkey %s does not exist",argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
StringDictUpdate(self->scripts,argv[2],argv[3]);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void listConfiguration(pMcStasController self, SConnection *pCon){
|
||||
Tcl_DString txt;
|
||||
char pLine[256];
|
||||
char pScript[131];
|
||||
|
||||
Tcl_DStringInit(&txt);
|
||||
StringDictGet(self->scripts,"mcstart",pScript,131);
|
||||
snprintf(pLine,255,"mccontrol.mcstart = %s\n",pScript);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
StringDictGet(self->scripts,"mcisrunning",pScript,131);
|
||||
snprintf(pLine,255,"mccontrol.mcisrunning = %s\n",pScript);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
StringDictGet(self->scripts,"mcdump",pScript,131);
|
||||
snprintf(pLine,255,"mccontrol.mcdump = %s\n",pScript);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
StringDictGet(self->scripts,"mckill",pScript,131);
|
||||
snprintf(pLine,255,"mccontrol.mckill = %s\n",pScript);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
StringDictGet(self->scripts,"mccopydata",pScript,131);
|
||||
snprintf(pLine,255,"mccontrol.mccopydata = %s\n",pScript);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
StringDictGet(self->scripts,"mcmonfile",pScript,131);
|
||||
snprintf(pLine,255,"mccontrol.mcmonfile = %s\n",pScript);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
snprintf(pLine,255,"mccontrol.updateintervall = %d\n",
|
||||
self->updateIntervall);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
snprintf(pLine,255,"mccontrol.monitorscale = %f\n",
|
||||
self->monitorScale);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
snprintf(pLine,255,"mccontrol.pid = %d", self->pid);
|
||||
Tcl_DStringAppend(&txt,pLine,-1);
|
||||
int McStasControllerFactory(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
pMcStasController pNew = NULL;
|
||||
|
||||
SCWrite(pCon,Tcl_DStringValue(&txt),eValue);
|
||||
Tcl_DStringFree(&txt);
|
||||
pNew = (pMcStasController) malloc(sizeof(McStasController));
|
||||
if (pNew == NULL) {
|
||||
SCWrite(pCon, "ERROR: out of memory creating McStasController",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pNew, 0, sizeof(McStasController));
|
||||
|
||||
pNew->pDes = CreateDescriptor("McStasController");
|
||||
pNew->scripts = CreateStringDict();
|
||||
if (pNew->pDes == NULL || pNew->scripts == NULL) {
|
||||
SCWrite(pCon, "ERROR: out of memory creating McStasController",
|
||||
eError);
|
||||
free(pNew);
|
||||
return 0;
|
||||
}
|
||||
StringDictAddPair(pNew->scripts, "mcstart", "UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts, "mcisrunning", "UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts, "mcdump", "UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts, "mckill", "UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts, "mccopydata", "UNDEFINED");
|
||||
StringDictAddPair(pNew->scripts, "mcmonfile", "UNDEFINED");
|
||||
pNew->pid = -1;
|
||||
pNew->monitorScale = 1;
|
||||
|
||||
return AddCommand(pSics, "mccontrol",
|
||||
McStasControllerWrapper, KillMcStasController, pNew);
|
||||
}
|
||||
|
||||
/*====================== interpreter interface ============================*/
|
||||
static int configureController(pMcStasController self, SConnection * pCon,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
char pBueffel[256];
|
||||
|
||||
if (argc < 4) {
|
||||
SCWrite(pCon,
|
||||
"ERRROR: insufficient number of arguments to mccontrol configure",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
strtolower(argv[2]);
|
||||
if (strcmp(argv[2], "update") == 0) {
|
||||
self->updateIntervall = atoi(argv[3]);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(argv[2], "monitorscale") == 0) {
|
||||
self->monitorScale = atof(argv[3]);
|
||||
if (self->monitorScale <= 0) {
|
||||
SCWrite(pCon, "ERROR: invalid monitor scale", eError);
|
||||
self->monitorScale = 1;
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
if (!StringDictExists(self->scripts, argv[2])) {
|
||||
snprintf(pBueffel, 255, "ERROR: scriptkey %s does not exist", argv[2]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
StringDictUpdate(self->scripts, argv[2], argv[3]);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void listConfiguration(pMcStasController self, SConnection * pCon)
|
||||
{
|
||||
Tcl_DString txt;
|
||||
char pLine[256];
|
||||
char pScript[131];
|
||||
|
||||
Tcl_DStringInit(&txt);
|
||||
StringDictGet(self->scripts, "mcstart", pScript, 131);
|
||||
snprintf(pLine, 255, "mccontrol.mcstart = %s\n", pScript);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
StringDictGet(self->scripts, "mcisrunning", pScript, 131);
|
||||
snprintf(pLine, 255, "mccontrol.mcisrunning = %s\n", pScript);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
StringDictGet(self->scripts, "mcdump", pScript, 131);
|
||||
snprintf(pLine, 255, "mccontrol.mcdump = %s\n", pScript);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
StringDictGet(self->scripts, "mckill", pScript, 131);
|
||||
snprintf(pLine, 255, "mccontrol.mckill = %s\n", pScript);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
StringDictGet(self->scripts, "mccopydata", pScript, 131);
|
||||
snprintf(pLine, 255, "mccontrol.mccopydata = %s\n", pScript);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
StringDictGet(self->scripts, "mcmonfile", pScript, 131);
|
||||
snprintf(pLine, 255, "mccontrol.mcmonfile = %s\n", pScript);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
snprintf(pLine, 255, "mccontrol.updateintervall = %d\n",
|
||||
self->updateIntervall);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
snprintf(pLine, 255, "mccontrol.monitorscale = %f\n",
|
||||
self->monitorScale);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
snprintf(pLine, 255, "mccontrol.pid = %d", self->pid);
|
||||
Tcl_DStringAppend(&txt, pLine, -1);
|
||||
|
||||
SCWrite(pCon, Tcl_DStringValue(&txt), eValue);
|
||||
Tcl_DStringFree(&txt);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int invokeScript(pMcStasController self, char *name, SicsInterp *pSics,
|
||||
char *result, int resultLen){
|
||||
char pCommand[256], pScript[132], pMode[10];
|
||||
Tcl_Interp *pTcl;
|
||||
int status;
|
||||
|
||||
if(!StringDictGet(self->scripts,name,pScript,131)){
|
||||
strncpy(result,"ERROR: script not found",resultLen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strcmp(name,"mccopydata") == 0){
|
||||
snprintf(pCommand,255,"%s",pScript);
|
||||
}else if(strcmp(name,"mcstart") == 0){
|
||||
if(self->mode == eTimer){
|
||||
strcpy(pMode,"timer");
|
||||
}else {
|
||||
strcpy(pMode,"monitor");
|
||||
}
|
||||
snprintf(pCommand,255,"%s %s %f", pScript,pMode,self->fPreset);
|
||||
} else {
|
||||
snprintf(pCommand,255,"%s %d",pScript,self->pid);
|
||||
}
|
||||
|
||||
pTcl = InterpGetTcl(pSics);
|
||||
status = Tcl_Eval(pTcl,pCommand);
|
||||
strncpy(result, pTcl->result, resultLen);
|
||||
if(status == TCL_OK){
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int runScript(pMcStasController self, SConnection *pCon,
|
||||
SicsInterp *pSics, int argc, char *argv[]){
|
||||
char pResult[256];
|
||||
int status;
|
||||
|
||||
if(argc < 3){
|
||||
SCWrite(pCon,
|
||||
"ERRROR: insufficient number of arguments to mccontrol run",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
status = invokeScript(self,argv[2],pSics,pResult,255);
|
||||
if(status == 1){
|
||||
SCWrite(pCon,pResult,eValue);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon,pResult,eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int start(pMcStasController self, SConnection *pCon){
|
||||
int status;
|
||||
static int invokeScript(pMcStasController self, char *name,
|
||||
SicsInterp * pSics, char *result, int resultLen)
|
||||
{
|
||||
char pCommand[256], pScript[132], pMode[10];
|
||||
Tcl_Interp *pTcl;
|
||||
int status;
|
||||
|
||||
status = McStasStart(self,eTimer,1000.);
|
||||
if(status != OKOK){
|
||||
SCWrite(pCon,self->errorText,eError);
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void wait4Finish(pMcStasController self){
|
||||
int status;
|
||||
|
||||
if(self->pid > 0){
|
||||
status = waitpid(self->pid,NULL,WNOHANG);
|
||||
if(status >= 0){
|
||||
self->pid = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int McStasControllerWrapper(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData, int argc, char *argv[]){
|
||||
pMcStasController self = NULL;
|
||||
char pBueffel[255], pFile[132];
|
||||
|
||||
self = (pMcStasController)pData;
|
||||
assert(self);
|
||||
if(argc < 2) {
|
||||
SCWrite(pCon,"ERROR: insufficient number of arguments to mccontrol",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"configure") == 0){
|
||||
return configureController(self,pCon,argc,argv);
|
||||
} else if(strcmp(argv[1],"list") == 0){
|
||||
listConfiguration(self,pCon);
|
||||
return 1;
|
||||
} else if(strcmp(argv[1],"run") == 0){
|
||||
return runScript(self,pCon,pSics,argc,argv);
|
||||
} else if(strcmp(argv[1],"start") == 0){
|
||||
return start(self,pCon);
|
||||
} else if(strcmp(argv[1],"finish") == 0){
|
||||
wait4Finish(self);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
if (!StringDictGet(self->scripts, name, pScript, 131)) {
|
||||
strncpy(result, "ERROR: script not found", resultLen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(name, "mccopydata") == 0) {
|
||||
snprintf(pCommand, 255, "%s", pScript);
|
||||
} else if (strcmp(name, "mcstart") == 0) {
|
||||
if (self->mode == eTimer) {
|
||||
strcpy(pMode, "timer");
|
||||
} else {
|
||||
snprintf(pBueffel,255,"ERROR: subcommand %s to mccontrol unknown",
|
||||
argv[1]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
strcpy(pMode, "monitor");
|
||||
}
|
||||
return 0;
|
||||
snprintf(pCommand, 255, "%s %s %f", pScript, pMode, self->fPreset);
|
||||
} else {
|
||||
snprintf(pCommand, 255, "%s %d", pScript, self->pid);
|
||||
}
|
||||
|
||||
pTcl = InterpGetTcl(pSics);
|
||||
status = Tcl_Eval(pTcl, pCommand);
|
||||
strncpy(result, pTcl->result, resultLen);
|
||||
if (status == TCL_OK) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int runScript(pMcStasController self, SConnection * pCon,
|
||||
SicsInterp * pSics, int argc, char *argv[])
|
||||
{
|
||||
char pResult[256];
|
||||
int status;
|
||||
|
||||
if (argc < 3) {
|
||||
SCWrite(pCon,
|
||||
"ERRROR: insufficient number of arguments to mccontrol run",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
status = invokeScript(self, argv[2], pSics, pResult, 255);
|
||||
if (status == 1) {
|
||||
SCWrite(pCon, pResult, eValue);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon, pResult, eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int start(pMcStasController self, SConnection * pCon)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = McStasStart(self, eTimer, 1000.);
|
||||
if (status != OKOK) {
|
||||
SCWrite(pCon, self->errorText, eError);
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void wait4Finish(pMcStasController self)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (self->pid > 0) {
|
||||
status = waitpid(self->pid, NULL, WNOHANG);
|
||||
if (status >= 0) {
|
||||
self->pid = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int McStasControllerWrapper(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
pMcStasController self = NULL;
|
||||
char pBueffel[255], pFile[132];
|
||||
|
||||
self = (pMcStasController) pData;
|
||||
assert(self);
|
||||
if (argc < 2) {
|
||||
SCWrite(pCon, "ERROR: insufficient number of arguments to mccontrol",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
strtolower(argv[1]);
|
||||
if (strcmp(argv[1], "configure") == 0) {
|
||||
return configureController(self, pCon, argc, argv);
|
||||
} else if (strcmp(argv[1], "list") == 0) {
|
||||
listConfiguration(self, pCon);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "run") == 0) {
|
||||
return runScript(self, pCon, pSics, argc, argv);
|
||||
} else if (strcmp(argv[1], "start") == 0) {
|
||||
return start(self, pCon);
|
||||
} else if (strcmp(argv[1], "finish") == 0) {
|
||||
wait4Finish(self);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else {
|
||||
snprintf(pBueffel, 255, "ERROR: subcommand %s to mccontrol unknown",
|
||||
argv[1]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*========================== the actual action functions =================*/
|
||||
int McStasStart(pMcStasController self, CounterMode mode, float fPreset){
|
||||
char pResult[256];
|
||||
int status;
|
||||
FILE *fd = NULL;
|
||||
|
||||
self->fPreset = fPreset;
|
||||
self->mode = mode;
|
||||
/**
|
||||
int McStasStart(pMcStasController self, CounterMode mode, float fPreset)
|
||||
{
|
||||
char pResult[256];
|
||||
int status;
|
||||
FILE *fd = NULL;
|
||||
|
||||
self->fPreset = fPreset;
|
||||
self->mode = mode;
|
||||
/**
|
||||
* make sure that the monitor file has only a 0 in it...
|
||||
*/
|
||||
if(!StringDictGet(self->scripts,"mcmonfile",pResult,255)){
|
||||
strncpy(self->errorText,"Misconfiguration: no monfile",255);
|
||||
return HWFault;
|
||||
}
|
||||
fd = fopen(pResult,"w");
|
||||
if(fd == NULL){
|
||||
strncpy(self->errorText,"Failed to access monitor file",255);
|
||||
return HWFault;
|
||||
}
|
||||
fprintf(fd,"0\n");
|
||||
fclose(fd);
|
||||
|
||||
/*
|
||||
* invoke start script
|
||||
*/
|
||||
status = invokeScript(self,"mcstart",pServ->pSics,pResult,255);
|
||||
if(status == 0){
|
||||
strncpy(self->errorText,pResult,255);
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/*
|
||||
* some general initializations ..
|
||||
*/
|
||||
self->pid = atoi(pResult);
|
||||
self->startTime = time(NULL);
|
||||
self->lastUpdate = self->startTime - self->updateIntervall;
|
||||
self->lastMonitorRead = self->startTime;
|
||||
return OKOK;
|
||||
if (!StringDictGet(self->scripts, "mcmonfile", pResult, 255)) {
|
||||
strncpy(self->errorText, "Misconfiguration: no monfile", 255);
|
||||
return HWFault;
|
||||
}
|
||||
fd = fopen(pResult, "w");
|
||||
if (fd == NULL) {
|
||||
strncpy(self->errorText, "Failed to access monitor file", 255);
|
||||
return HWFault;
|
||||
}
|
||||
fprintf(fd, "0\n");
|
||||
fclose(fd);
|
||||
|
||||
/*
|
||||
* invoke start script
|
||||
*/
|
||||
status = invokeScript(self, "mcstart", pServ->pSics, pResult, 255);
|
||||
if (status == 0) {
|
||||
strncpy(self->errorText, pResult, 255);
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/*
|
||||
* some general initializations ..
|
||||
*/
|
||||
self->pid = atoi(pResult);
|
||||
self->startTime = time(NULL);
|
||||
self->lastUpdate = self->startTime - self->updateIntervall;
|
||||
self->lastMonitorRead = self->startTime;
|
||||
return OKOK;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static long readMonFile(pMcStasController self){
|
||||
char pResult[256];
|
||||
FILE *fd = NULL;
|
||||
long monValue = -1;
|
||||
int i;
|
||||
|
||||
if(!StringDictGet(self->scripts,"mcmonfile",pResult,255)){
|
||||
return -1;
|
||||
}
|
||||
static long readMonFile(pMcStasController self)
|
||||
{
|
||||
char pResult[256];
|
||||
FILE *fd = NULL;
|
||||
long monValue = -1;
|
||||
int i;
|
||||
|
||||
fd = fopen(pResult,"r");
|
||||
if(fd != NULL){
|
||||
fscanf(fd,"%ld", &monValue);
|
||||
fclose(fd);
|
||||
}
|
||||
return monValue;
|
||||
if (!StringDictGet(self->scripts, "mcmonfile", pResult, 255)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = fopen(pResult, "r");
|
||||
if (fd != NULL) {
|
||||
fscanf(fd, "%ld", &monValue);
|
||||
fclose(fd);
|
||||
}
|
||||
return monValue;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
int McStasStatus(pMcStasController self, float *fControl){
|
||||
char pResult[256];
|
||||
float monValue;
|
||||
int status, i;
|
||||
int McStasStatus(pMcStasController self, float *fControl)
|
||||
{
|
||||
char pResult[256];
|
||||
float monValue;
|
||||
int status, i;
|
||||
|
||||
/*
|
||||
* check at max any second, else SICS keeps the system busy and
|
||||
* there is no CPU left for McStas
|
||||
*/
|
||||
SicsWait(1);
|
||||
status = invokeScript(self,"mcisrunning",pServ->pSics,pResult, 255);
|
||||
if(status == 0){
|
||||
strncpy(self->errorText,pResult,255);
|
||||
return HWFault;
|
||||
}
|
||||
status = atoi(pResult);
|
||||
/*
|
||||
* handle timer mode
|
||||
*/
|
||||
if(status == 1 && self->mode == eTimer &&
|
||||
time(NULL) >= self->startTime + (int)self->fPreset){
|
||||
McStasStop(self);
|
||||
return HWBusy;
|
||||
} else {
|
||||
*fControl = time(NULL) - self->startTime;
|
||||
}
|
||||
/*
|
||||
* handle monitor mode
|
||||
*/
|
||||
if(status == 1 && self->mode == ePreset){
|
||||
/*
|
||||
* check only any three seconds, else SICS uses up all the CPU time
|
||||
* and the simulation has no chance.
|
||||
*/
|
||||
*fControl = self->lastMon;
|
||||
if(time(NULL) < self->lastMonitorRead + 3) {
|
||||
return HWBusy;
|
||||
}
|
||||
monValue = -1;
|
||||
/*
|
||||
* try to read the monfile up to three times. Problems reading it
|
||||
* can be synchronisation problems with McStas
|
||||
*/
|
||||
for(i = 0, monValue = -1; i < 7; i++){
|
||||
monValue = (float)readMonFile(self);
|
||||
if(monValue >= 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(monValue < 0){
|
||||
return HWBusy;
|
||||
}
|
||||
self->lastMonitorRead = time(NULL);
|
||||
monValue *= self->monitorScale;
|
||||
*fControl = monValue;
|
||||
self->lastMon = monValue;
|
||||
if(monValue >= self->fPreset){
|
||||
McStasStop(self);
|
||||
}
|
||||
}
|
||||
|
||||
if(status == 1){
|
||||
return HWBusy;
|
||||
} else {
|
||||
self->stopTime = time(NULL);
|
||||
self->pid = -1;
|
||||
return HWIdle;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int McStasStop(pMcStasController self){
|
||||
char pResult[256];
|
||||
invokeScript(self,"mckill",pServ->pSics,pResult, 255);
|
||||
self->lastUpdate = time(NULL) - 3*self->updateIntervall;
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int McStasTransferData(pMcStasController self){
|
||||
char pResult[256];
|
||||
int status;
|
||||
|
||||
/*
|
||||
* prevent to frequent requests
|
||||
*/
|
||||
if(self->lastUpdate + self->updateIntervall > time(NULL)){
|
||||
return OKOK;
|
||||
}
|
||||
/*
|
||||
* check at max any second, else SICS keeps the system busy and
|
||||
* there is no CPU left for McStas
|
||||
*/
|
||||
SicsWait(1);
|
||||
status = invokeScript(self, "mcisrunning", pServ->pSics, pResult, 255);
|
||||
if (status == 0) {
|
||||
strncpy(self->errorText, pResult, 255);
|
||||
return HWFault;
|
||||
}
|
||||
status = atoi(pResult);
|
||||
/*
|
||||
* handle timer mode
|
||||
*/
|
||||
if (status == 1 && self->mode == eTimer &&
|
||||
time(NULL) >= self->startTime + (int) self->fPreset) {
|
||||
McStasStop(self);
|
||||
return HWBusy;
|
||||
} else {
|
||||
*fControl = time(NULL) - self->startTime;
|
||||
}
|
||||
/*
|
||||
* handle monitor mode
|
||||
*/
|
||||
if (status == 1 && self->mode == ePreset) {
|
||||
/*
|
||||
* check only any three seconds, else SICS uses up all the CPU time
|
||||
* and the simulation has no chance.
|
||||
*/
|
||||
*fControl = self->lastMon;
|
||||
if (time(NULL) < self->lastMonitorRead + 3) {
|
||||
return HWBusy;
|
||||
}
|
||||
monValue = -1;
|
||||
/*
|
||||
* try to read the monfile up to three times. Problems reading it
|
||||
* can be synchronisation problems with McStas
|
||||
*/
|
||||
for (i = 0, monValue = -1; i < 7; i++) {
|
||||
monValue = (float) readMonFile(self);
|
||||
if (monValue >= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (monValue < 0) {
|
||||
return HWBusy;
|
||||
}
|
||||
self->lastMonitorRead = time(NULL);
|
||||
monValue *= self->monitorScale;
|
||||
*fControl = monValue;
|
||||
self->lastMon = monValue;
|
||||
if (monValue >= self->fPreset) {
|
||||
McStasStop(self);
|
||||
}
|
||||
}
|
||||
|
||||
self->lastUpdate = time(NULL);
|
||||
if(self->pid >= 0){
|
||||
status = invokeScript(self,"mcdump",pServ->pSics,pResult, 255);
|
||||
if(status == 0){
|
||||
strncpy(self->errorText,pResult,255);
|
||||
self->lastUpdate = time(NULL) - self->updateIntervall;
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
|
||||
status = invokeScript(self,"mccopydata",pServ->pSics,pResult, 255);
|
||||
if(status == 0){
|
||||
strncpy(self->errorText,pResult,255);
|
||||
self->lastUpdate = time(NULL) - self->updateIntervall;
|
||||
return HWFault;
|
||||
}
|
||||
return OKOK;
|
||||
if (status == 1) {
|
||||
return HWBusy;
|
||||
} else {
|
||||
self->stopTime = time(NULL);
|
||||
self->pid = -1;
|
||||
return HWIdle;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int McStasGetError(pMcStasController self, char *error, int errLen){
|
||||
strncpy(error,self->errorText,errLen);
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int McStasFix(pMcStasController self){
|
||||
/*
|
||||
* if the monitor file cannot be read, this may be caused by
|
||||
* a conflict of mCstas writing while we are reading. let us
|
||||
* retry...
|
||||
*/
|
||||
if(strstr(self->errorText,"monitor") != NULL){
|
||||
return COREDO;
|
||||
}
|
||||
/*
|
||||
* you have to edit the scripts to fix anything which is going wrong here.
|
||||
* But make sure the simulation is stopped.
|
||||
*/
|
||||
McStasStop(self);
|
||||
self->stopTime = time(NULL);
|
||||
self->pid = -1;
|
||||
return COTERM;
|
||||
int McStasStop(pMcStasController self)
|
||||
{
|
||||
char pResult[256];
|
||||
invokeScript(self, "mckill", pServ->pSics, pResult, 255);
|
||||
self->lastUpdate = time(NULL) - 3 * self->updateIntervall;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
float McStasGetTime(pMcStasController self){
|
||||
if(self->pid < 0){
|
||||
return (float)(self->stopTime - self->startTime);
|
||||
} else {
|
||||
return (float)time(NULL) - self->startTime;
|
||||
}
|
||||
int McStasTransferData(pMcStasController self)
|
||||
{
|
||||
char pResult[256];
|
||||
int status;
|
||||
|
||||
/*
|
||||
* prevent to frequent requests
|
||||
*/
|
||||
if (self->lastUpdate + self->updateIntervall > time(NULL)) {
|
||||
return OKOK;
|
||||
}
|
||||
|
||||
self->lastUpdate = time(NULL);
|
||||
if (self->pid >= 0) {
|
||||
status = invokeScript(self, "mcdump", pServ->pSics, pResult, 255);
|
||||
if (status == 0) {
|
||||
strncpy(self->errorText, pResult, 255);
|
||||
self->lastUpdate = time(NULL) - self->updateIntervall;
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
|
||||
status = invokeScript(self, "mccopydata", pServ->pSics, pResult, 255);
|
||||
if (status == 0) {
|
||||
strncpy(self->errorText, pResult, 255);
|
||||
self->lastUpdate = time(NULL) - self->updateIntervall;
|
||||
return HWFault;
|
||||
}
|
||||
return OKOK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int McStasGetError(pMcStasController self, char *error, int errLen)
|
||||
{
|
||||
strncpy(error, self->errorText, errLen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int McStasFix(pMcStasController self)
|
||||
{
|
||||
/*
|
||||
* if the monitor file cannot be read, this may be caused by
|
||||
* a conflict of mCstas writing while we are reading. let us
|
||||
* retry...
|
||||
*/
|
||||
if (strstr(self->errorText, "monitor") != NULL) {
|
||||
return COREDO;
|
||||
}
|
||||
/*
|
||||
* you have to edit the scripts to fix anything which is going wrong here.
|
||||
* But make sure the simulation is stopped.
|
||||
*/
|
||||
McStasStop(self);
|
||||
self->stopTime = time(NULL);
|
||||
self->pid = -1;
|
||||
return COTERM;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
float McStasGetTime(pMcStasController self)
|
||||
{
|
||||
if (self->pid < 0) {
|
||||
return (float) (self->stopTime - self->startTime);
|
||||
} else {
|
||||
return (float) time(NULL) - self->startTime;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user