From 4fb94efe9a3f3f5e7402f689c5b523a7cf18f011 Mon Sep 17 00:00:00 2001 From: Mark Koennecke Date: Fri, 27 Jun 2014 11:05:27 +0200 Subject: [PATCH] This is the first version of the newly refactored status code handling. Status codes are now determined by a special task which inspects SICS for what is going on. Before this was a global variable which caused conflicts when multiple instances in the code tried to set it. --- SCinter.h | 2 +- devexec.c | 9 +++ devexec.w | 2 + exeman.c | 11 +++- exeman.h | 2 + interface.c | 4 ++ nserver.c | 3 + scan.c | 6 +- scan.h | 1 + status.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++--- status.h | 1 + task.c | 5 ++ task.h | 5 +- 13 files changed, 206 insertions(+), 12 deletions(-) diff --git a/SCinter.h b/SCinter.h index 33147ac8..255e8db6 100644 --- a/SCinter.h +++ b/SCinter.h @@ -155,7 +155,7 @@ void *FindCommandData(SicsInterp * pSics, char *name, char *comclass); */ pObjectDescriptor FindCommandDescriptor(SicsInterp * pSics, char *name); -/*------------------------------------------------------------------------ +/*--------------------------------------------------------------------- FindDrivable tries to find Drivable object by the name given. Returns a pointer to the drivable interface in the case of success, NULL in case of failure. In order to save me fixing header files the pointer must diff --git a/devexec.c b/devexec.c index 7979d9eb..964ce5b6 100644 --- a/devexec.c +++ b/devexec.c @@ -965,3 +965,12 @@ void SetDevexecStatus(pExeList pExe, int code) pExe->iStatus = code; } } +/*------------------------------------------------------------------------*/ +int GetDevExecInstStatus(pExeList self) +{ + if(self->lTask < 0){ + return eEager; + } else { + return self->instStatus; + } +} \ No newline at end of file diff --git a/devexec.w b/devexec.w index dafc2a21..403e60eb 100644 --- a/devexec.w +++ b/devexec.w @@ -101,6 +101,8 @@ From within the SICS main loops this special function is called: int DevExecTask(void *pEL); void DevExecSignal(void *pEL, int iSignal, void *pSigData); + int GetDevExecInstStatus(pExeList self); + @} CheckExeList then scan through its list of executing objects and request a status from each of them. The next action depend on the status returned from diff --git a/exeman.c b/exeman.c index 40301635..55ae402a 100644 --- a/exeman.c +++ b/exeman.c @@ -224,7 +224,16 @@ pDynString findBatchFile(SicsInterp * pSics, char *name) } return locateBatchBuffer(self, name); } - +/*--------------------------------------------------------------------*/ +int isBatchRunning() +{ + pExeMan self = (pExeMan) FindCommandData(pServ->pSics, "exe", "ExeManager"); + if(self != NULL && self->exeStackPtr > 0){ + return 1; + } else { + return 0; + } +} /*--------------------------------------------------------------------*/ static int runBatchBuffer(pExeMan self, SConnection * pCon, SicsInterp * pSics, char *name) diff --git a/exeman.h b/exeman.h index fc110a6e..0718c67f 100644 --- a/exeman.h +++ b/exeman.h @@ -19,4 +19,6 @@ pDynString findBatchFile(SicsInterp * pSics, char *name); int exeHdbBuffer(SConnection * pCon, SicsInterp * pSics, char *name); int exeHdbNode(pHdb exeNode, SConnection * pCon); +int isBatchRunning(); + #endif diff --git a/interface.c b/interface.c index c10fe697..9ab9c52a 100644 --- a/interface.c +++ b/interface.c @@ -176,6 +176,7 @@ int GetDrivablePosition(void *pObject, SConnection * pCon, float *fPos) } /*--------------------------------------------------------------------------*/ typedef struct { + int id; void *obj; pIDrivable pDriv; SConnection *pCon; @@ -271,6 +272,7 @@ long StartDriveTask(void *obj, SConnection *pCon, char *name, float fTarget) DevexecLog("START",name); InvokeNewTarget(pServ->pExecutor,name,fTarget); + taskData->id = DRIVEID; taskData->obj = obj; taskData->pDriv = pDriv; taskData->pCon = SCCopyConnection(pCon); @@ -317,6 +319,7 @@ int isRunning(pICountable self) } /*--------------------------------------------------------------------------*/ typedef struct { + int id; void *obj; pICountable pCount; SConnection *pCon; @@ -416,6 +419,7 @@ long StartCountTask(void *obj, SConnection *pCon, char *name) ExeInterest(pServ->pExecutor,name,"started"); DevexecLog("START",name); + taskData->id = COUNTID; taskData->obj = obj; taskData->pCount = pCount; taskData->pCon = SCCopyConnection(pCon); diff --git a/nserver.c b/nserver.c index 6356a6e8..e87287fb 100644 --- a/nserver.c +++ b/nserver.c @@ -263,6 +263,9 @@ int InitServer(char *file, pServer * pServ) INIT(StatusFileInit); + /* install status task */ + InitStatus(); + /* exit handlers need to be installed here */ atexit(StopExit); (void)Fortify_CheckAllMemory(); diff --git a/scan.c b/scan.c index 42f74e01..3d9823dd 100644 --- a/scan.c +++ b/scan.c @@ -999,7 +999,11 @@ int GetScanVarName(pScanData self, int iWhich, char *pName, int iLength) return 0; } } - +/*---------------------------------------------------------------------*/ +int isScanRunning(pScanData self) +{ + return self->iActive; +} /*---------------------------------------------------------------------*/ int GetScanVarStep(pScanData self, int iWhich, float *fStep) { diff --git a/scan.h b/scan.h index f9e2ca2e..37e13960 100644 --- a/scan.h +++ b/scan.h @@ -40,6 +40,7 @@ int GetScanVarStep(pScanData self, int iWhich, float *fStep); int GetScanMonitor(pScanData self, int iWhich, long *lData, int iDataLen); int GetScanNP(pScanData self); float GetScanPreset(pScanData self); +int isScanRunning(pScanData self); int ScanIntegrate(pScanData self, float *fSum, float *fVariance); diff --git a/status.c b/status.c index 34a0bbad..0d7ba93d 100644 --- a/status.c +++ b/status.c @@ -52,6 +52,9 @@ #include "status.h" #include "interrupt.h" #include "sicshipadaba.h" +#include "messagepipe.h" +#include "scan.h" +#include "exeman.h" #undef VALUECHANGE #define VALUECHANGE 2 @@ -97,6 +100,8 @@ static char *iText[] = { static pICallBack pCall = NULL; static int fixed = 0; static Status eCode = eEager; +static int userWait = 0; +static double lastStatus = .0; /*-------------------------------------------------------------------------*/ void KillStatus(void *pData) { @@ -108,24 +113,35 @@ void KillStatus(void *pData) /*--------------------------------------------------------------------------*/ void SetStatus(Status eNew) { - if (!fixed) { +/* if (!fixed) { if (eCode == eNew) { return; } eCode = eNew; InvokeCallBack(pCall, VALUECHANGE, NULL); } +*/ + /* + This now only manages the userWait status + */ + if(eNew == eUserWait){ + userWait = 1; + } else { + if(userWait == 1){ + userWait = 0; + } + } } /*----------------------------------------------------------------------*/ void SetStatusFixed(Status eNew) { - if (eCode == eNew) { - return; - } - eCode = eNew; - InvokeCallBack(pCall, VALUECHANGE, NULL); - fixed = 1; + // if (eCode == eNew) { + // return; + // } + // eCode = eNew; + // InvokeCallBack(pCall, VALUECHANGE, NULL); + // fixed = 1; } /*----------------------------------------------------------------------*/ @@ -279,7 +295,9 @@ int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData, SCWrite(pCon, "Insufficient authorisation to reset server", eError); return 0; } - SetStatus(eEager); + // SetStatus(eEager); + eCode = eEager; + InvokeCallBack(pCall, VALUECHANGE, NULL); SetInterrupt(eContinue); ClearExecutor(GetExecutor()); SCsetMacro(pCon, 0); @@ -337,3 +355,136 @@ int RedirectControl(SConnection * pCon, SicsInterp * pSics, void *pData, pOwner->sockHandle = pCon->sockHandle; return 1; } +/*---------------------------------------------------------------------------- +Message pipe based new status calculation code +------------------------------------------------------------------------------*/ + +static int DevexecStatusFunc(void *message, void *userData) +{ + + int *status = (int *)message; + + *status = GetDevExecInstStatus(pServ->pExecutor); + return MPCONTINUE; +} +/*----------------------------------------------------------------------------- +This must be identical to the definition in interface.c As this structure is only +required in interface.c and here, I choose not to put it into an header file. +-------------------------------------------------------------------------------*/ +typedef struct { + int id; + void *obj; + pICountable pCount; + SConnection *pCon; + char *name; +}CountTaskData; +/*-----------------------------------------------------------------------------*/ +static int CheckCountStatus(void *message, void *userData) +{ + int *status = (int *)message; + int testStatus; + pTaskHead it; + CountTaskData *countTask = NULL; + + if(*status == eCounting){ + for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){ + countTask = (CountTaskData *)GetTaskData(it); + if(countTask != NULL && countTask->id == COUNTID){ + testStatus = countTask->pCount->CheckCountStatus(countTask->obj,pServ->dummyCon); + if(testStatus == HWNoBeam){ + *status = eOutOfBeam; + } + if(testStatus == HWPause){ + *status = ePaused; + } + } + } + return MPSTOP; + } + return MPCONTINUE; +} +/*---------------------------------------------------------------------------*/ +static pScanData scan = NULL; +static int CheckScan(void *message, void *userData) +{ + char *scannames[] = {"xxxscan","iscan", NULL}; + unsigned int count = 0; + int *status = (int *)message; + + if(*status == eEager){ + if(scan == NULL){ + while(scannames[count] != NULL){ + scan = FindCommandData(pServ->pSics, scannames[count],NULL); + if(scan != NULL){ + break; + } + count++; + } + } + + if(scan != NULL){ + if(isScanRunning(scan)){ + *status = eScanning; + return MPCONTINUE; + } + } +} +return MPCONTINUE; +} +/*----------------------------------------------------------------------------*/ + +static int CheckExe(void *message, void *userData) +{ + int *status = (int *)message; + + if(*status == eEager){ + if(isBatchRunning()){ + *status = eBatch; + } + } + return MPCONTINUE; +} +/*------------------------------------------------------------------------------*/ +static int CheckUserWait(void *message, void *userData) +{ + int *status = (int *)message; + + if(*status == eEager){ + if(isTaskRunning(pServ->pTasker,"wait")){ + *status = eUserWait; + } + } + return MPCONTINUE; +} +/*--------------------------------------------------------------------------------*/ +static pMP statusPipe = NULL; + +static void BuildStatusChain(void) +{ + statusPipe = MakeMP(); + AppendMPFilter(statusPipe,DevexecStatusFunc,NULL,NULL); + AppendMPFilter(statusPipe,CheckCountStatus,NULL,NULL); + AppendMPFilter(statusPipe,CheckScan,NULL,NULL); + AppendMPFilter(statusPipe,CheckExe,NULL,NULL); + AppendMPFilter(statusPipe,CheckUserWait,NULL,NULL); +} +/*-------------------------------------------------------------------------------*/ +static int StatusTask(void *data) +{ + int status = eEager; + + MPprocess(statusPipe,&status); + if(status != eCode && DoubleTime() > lastStatus + .1){ + eCode = status; + lastStatus = DoubleTime(); + InvokeCallBack(pCall, VALUECHANGE, NULL); + } + + return 1; +} +/*---------------------------------------------------------------------------------*/ +void InitStatus(void) +{ + BuildStatusChain(); + TaskRegisterN(pServ->pTasker,"statustask",StatusTask, NULL, NULL, NULL,1); +} diff --git a/status.h b/status.h index 468e0354..5d38f2b4 100644 --- a/status.h +++ b/status.h @@ -49,5 +49,6 @@ int UserStatus(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); +void InitStatus(void); #endif diff --git a/task.c b/task.c index be911cdc..8e338657 100644 --- a/task.c +++ b/task.c @@ -544,6 +544,11 @@ const char * GetTaskName(pTaskHead it) return (const char*)it->name; } /*------------------------------------------------------------------------------*/ +const void *GetTaskData(pTaskHead it) +{ + return (const void*)it->pData; +} +/*------------------------------------------------------------------------------*/ long GetTaskGroupID(pTaskMan self) { lIDMama++; diff --git a/task.h b/task.h index 4cd0c729..03d6636c 100644 --- a/task.h +++ b/task.h @@ -197,7 +197,10 @@ const char *GetTaskName(pTaskHead it); /* get the name of the current task. Do not delete the returned pointer. */ - +const void *GetTaskData(pTaskHead it); +/* + Get the user data for the current task. Do not free the returned pointer! +*/ /*============================================================================= Task Groups. The implementation has the limit that any given task can only be member of one task group