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:
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
11
exeman.c
11
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)
|
||||
|
2
exeman.h
2
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
|
||||
|
@ -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);
|
||||
|
@ -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
6
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)
|
||||
{
|
||||
|
1
scan.h
1
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);
|
||||
|
||||
|
167
status.c
167
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);
|
||||
}
|
||||
|
1
status.h
1
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
|
||||
|
5
task.c
5
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++;
|
||||
|
5
task.h
5
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
|
||||
|
Reference in New Issue
Block a user