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.
This commit is contained in:
2014-06-27 11:05:27 +02:00
parent d6faaa593a
commit 4fb94efe9a
13 changed files with 206 additions and 12 deletions

View File

@ -155,7 +155,7 @@ void *FindCommandData(SicsInterp * pSics, char *name, char *comclass);
*/ */
pObjectDescriptor FindCommandDescriptor(SicsInterp * pSics, char *name); pObjectDescriptor FindCommandDescriptor(SicsInterp * pSics, char *name);
/*------------------------------------------------------------------------ /*---------------------------------------------------------------------
FindDrivable tries to find Drivable object by the name given. Returns a FindDrivable tries to find Drivable object by the name given. Returns a
pointer to the drivable interface in the case of success, NULL in 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 case of failure. In order to save me fixing header files the pointer must

View File

@ -965,3 +965,12 @@ void SetDevexecStatus(pExeList pExe, int code)
pExe->iStatus = code; pExe->iStatus = code;
} }
} }
/*------------------------------------------------------------------------*/
int GetDevExecInstStatus(pExeList self)
{
if(self->lTask < 0){
return eEager;
} else {
return self->instStatus;
}
}

View File

@ -101,6 +101,8 @@ From within the SICS main loops this special function is called:
int DevExecTask(void *pEL); int DevExecTask(void *pEL);
void DevExecSignal(void *pEL, int iSignal, void *pSigData); void DevExecSignal(void *pEL, int iSignal, void *pSigData);
int GetDevExecInstStatus(pExeList self);
@} @}
CheckExeList then scan through its list of executing objects and request a 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 status from each of them. The next action depend on the status returned from

View File

@ -224,7 +224,16 @@ pDynString findBatchFile(SicsInterp * pSics, char *name)
} }
return locateBatchBuffer(self, 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, static int runBatchBuffer(pExeMan self, SConnection * pCon,
SicsInterp * pSics, char *name) SicsInterp * pSics, char *name)

View File

@ -19,4 +19,6 @@ pDynString findBatchFile(SicsInterp * pSics, char *name);
int exeHdbBuffer(SConnection * pCon, SicsInterp * pSics, char *name); int exeHdbBuffer(SConnection * pCon, SicsInterp * pSics, char *name);
int exeHdbNode(pHdb exeNode, SConnection * pCon); int exeHdbNode(pHdb exeNode, SConnection * pCon);
int isBatchRunning();
#endif #endif

View File

@ -176,6 +176,7 @@ int GetDrivablePosition(void *pObject, SConnection * pCon, float *fPos)
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
typedef struct { typedef struct {
int id;
void *obj; void *obj;
pIDrivable pDriv; pIDrivable pDriv;
SConnection *pCon; SConnection *pCon;
@ -271,6 +272,7 @@ long StartDriveTask(void *obj, SConnection *pCon, char *name, float fTarget)
DevexecLog("START",name); DevexecLog("START",name);
InvokeNewTarget(pServ->pExecutor,name,fTarget); InvokeNewTarget(pServ->pExecutor,name,fTarget);
taskData->id = DRIVEID;
taskData->obj = obj; taskData->obj = obj;
taskData->pDriv = pDriv; taskData->pDriv = pDriv;
taskData->pCon = SCCopyConnection(pCon); taskData->pCon = SCCopyConnection(pCon);
@ -317,6 +319,7 @@ int isRunning(pICountable self)
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
typedef struct { typedef struct {
int id;
void *obj; void *obj;
pICountable pCount; pICountable pCount;
SConnection *pCon; SConnection *pCon;
@ -416,6 +419,7 @@ long StartCountTask(void *obj, SConnection *pCon, char *name)
ExeInterest(pServ->pExecutor,name,"started"); ExeInterest(pServ->pExecutor,name,"started");
DevexecLog("START",name); DevexecLog("START",name);
taskData->id = COUNTID;
taskData->obj = obj; taskData->obj = obj;
taskData->pCount = pCount; taskData->pCount = pCount;
taskData->pCon = SCCopyConnection(pCon); taskData->pCon = SCCopyConnection(pCon);

View File

@ -263,6 +263,9 @@ int InitServer(char *file, pServer * pServ)
INIT(StatusFileInit); INIT(StatusFileInit);
/* install status task */
InitStatus();
/* exit handlers need to be installed here */ /* exit handlers need to be installed here */
atexit(StopExit); atexit(StopExit);
(void)Fortify_CheckAllMemory(); (void)Fortify_CheckAllMemory();

6
scan.c
View File

@ -999,7 +999,11 @@ int GetScanVarName(pScanData self, int iWhich, char *pName, int iLength)
return 0; return 0;
} }
} }
/*---------------------------------------------------------------------*/
int isScanRunning(pScanData self)
{
return self->iActive;
}
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
int GetScanVarStep(pScanData self, int iWhich, float *fStep) int GetScanVarStep(pScanData self, int iWhich, float *fStep)
{ {

1
scan.h
View File

@ -40,6 +40,7 @@ int GetScanVarStep(pScanData self, int iWhich, float *fStep);
int GetScanMonitor(pScanData self, int iWhich, long *lData, int iDataLen); int GetScanMonitor(pScanData self, int iWhich, long *lData, int iDataLen);
int GetScanNP(pScanData self); int GetScanNP(pScanData self);
float GetScanPreset(pScanData self); float GetScanPreset(pScanData self);
int isScanRunning(pScanData self);
int ScanIntegrate(pScanData self, float *fSum, float *fVariance); int ScanIntegrate(pScanData self, float *fSum, float *fVariance);

167
status.c
View File

@ -52,6 +52,9 @@
#include "status.h" #include "status.h"
#include "interrupt.h" #include "interrupt.h"
#include "sicshipadaba.h" #include "sicshipadaba.h"
#include "messagepipe.h"
#include "scan.h"
#include "exeman.h"
#undef VALUECHANGE #undef VALUECHANGE
#define VALUECHANGE 2 #define VALUECHANGE 2
@ -97,6 +100,8 @@ static char *iText[] = {
static pICallBack pCall = NULL; static pICallBack pCall = NULL;
static int fixed = 0; static int fixed = 0;
static Status eCode = eEager; static Status eCode = eEager;
static int userWait = 0;
static double lastStatus = .0;
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
void KillStatus(void *pData) void KillStatus(void *pData)
{ {
@ -108,24 +113,35 @@ void KillStatus(void *pData)
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void SetStatus(Status eNew) void SetStatus(Status eNew)
{ {
if (!fixed) { /* if (!fixed) {
if (eCode == eNew) { if (eCode == eNew) {
return; return;
} }
eCode = eNew; eCode = eNew;
InvokeCallBack(pCall, VALUECHANGE, NULL); 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) void SetStatusFixed(Status eNew)
{ {
if (eCode == eNew) { // if (eCode == eNew) {
return; // return;
} // }
eCode = eNew; // eCode = eNew;
InvokeCallBack(pCall, VALUECHANGE, NULL); // InvokeCallBack(pCall, VALUECHANGE, NULL);
fixed = 1; // fixed = 1;
} }
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
@ -279,7 +295,9 @@ int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, "Insufficient authorisation to reset server", eError); SCWrite(pCon, "Insufficient authorisation to reset server", eError);
return 0; return 0;
} }
SetStatus(eEager); // SetStatus(eEager);
eCode = eEager;
InvokeCallBack(pCall, VALUECHANGE, NULL);
SetInterrupt(eContinue); SetInterrupt(eContinue);
ClearExecutor(GetExecutor()); ClearExecutor(GetExecutor());
SCsetMacro(pCon, 0); SCsetMacro(pCon, 0);
@ -337,3 +355,136 @@ int RedirectControl(SConnection * pCon, SicsInterp * pSics, void *pData,
pOwner->sockHandle = pCon->sockHandle; pOwner->sockHandle = pCon->sockHandle;
return 1; 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);
}

View File

@ -49,5 +49,6 @@ int UserStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]); int argc, char *argv[]);
int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData, int ResetStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]); int argc, char *argv[]);
void InitStatus(void);
#endif #endif

5
task.c
View File

@ -544,6 +544,11 @@ const char * GetTaskName(pTaskHead it)
return (const char*)it->name; return (const char*)it->name;
} }
/*------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------*/
const void *GetTaskData(pTaskHead it)
{
return (const void*)it->pData;
}
/*------------------------------------------------------------------------------*/
long GetTaskGroupID(pTaskMan self) long GetTaskGroupID(pTaskMan self)
{ {
lIDMama++; lIDMama++;

5
task.h
View File

@ -197,7 +197,10 @@ const char *GetTaskName(pTaskHead it);
/* /*
get the name of the current task. Do not delete the returned pointer. 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 Task Groups. The implementation has the limit that any given task can
only be member of one task group only be member of one task group