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);
/*------------------------------------------------------------------------
/*---------------------------------------------------------------------
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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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();

6
scan.c
View File

@ -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)
{

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 GetScanNP(pScanData self);
float GetScanPreset(pScanData self);
int isScanRunning(pScanData self);
int ScanIntegrate(pScanData self, float *fSum, float *fVariance);

167
status.c
View File

@ -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);
}

View File

@ -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

5
task.c
View File

@ -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++;

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.
*/
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