- Fixed a bug in hklscan: core dump when writing to file
- Fixed two small issues with evcontroller: no test for privilege on drive - Many changes to AMOR software.
This commit is contained in:
417
amor2t.c
417
amor2t.c
@ -12,6 +12,13 @@
|
|||||||
copyright: see copyright.h
|
copyright: see copyright.h
|
||||||
|
|
||||||
Mark Koennecke, September 1999
|
Mark Koennecke, September 1999
|
||||||
|
|
||||||
|
Bugs fixed, analyzer included for A2T. Then there is a second thing:
|
||||||
|
aoz2t which allows to scan the analyzer in two-theta during alignment
|
||||||
|
of the instrument. As all the parameters are already held in the a2t
|
||||||
|
structures this extra was added into this module.
|
||||||
|
|
||||||
|
Mark Koennecke, May-June 2000
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -24,8 +31,8 @@
|
|||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
|
|
||||||
#define MAXMOT 9
|
#define MAXMOT 13
|
||||||
#define MAXPAR 8
|
#define MAXPAR 13
|
||||||
|
|
||||||
#include "amor2t.i"
|
#include "amor2t.i"
|
||||||
#include "amor2t.h"
|
#include "amor2t.h"
|
||||||
@ -53,6 +60,12 @@
|
|||||||
#define MOTD5B 7
|
#define MOTD5B 7
|
||||||
/* detector omega movement */
|
/* detector omega movement */
|
||||||
#define MOTCOM 8
|
#define MOTCOM 8
|
||||||
|
/* lift for analyzer */
|
||||||
|
#define MOTAOZ 9
|
||||||
|
/* analyzer omega */
|
||||||
|
#define MOTAOM 10
|
||||||
|
/* detector 2 movement */
|
||||||
|
#define MOTC3Z 11
|
||||||
|
|
||||||
/* distance detector sample */
|
/* distance detector sample */
|
||||||
#define PARDS 0
|
#define PARDS 0
|
||||||
@ -70,16 +83,25 @@
|
|||||||
#define PARD4H 6
|
#define PARD4H 6
|
||||||
/* height of D5 */
|
/* height of D5 */
|
||||||
#define PARD5H 7
|
#define PARD5H 7
|
||||||
|
/* base height of analyzer */
|
||||||
|
#define PARANA 8
|
||||||
|
/* distance of analyzer from sample */
|
||||||
|
#define PARADIS 9
|
||||||
|
/* flag analyzer calculation on/off */
|
||||||
|
#define ANAFLAG 10
|
||||||
|
/* constant for second detector */
|
||||||
|
#define PARDDD 11
|
||||||
|
/* constant part of AOM */
|
||||||
|
#define PARAOM 12
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
The core of it all: The calculation of the settings for the various
|
The core of it all: The calculation of the settings for the various
|
||||||
motors.
|
motors.
|
||||||
========================================================================*/
|
========================================================================*/
|
||||||
|
|
||||||
static int CalculateAMORE(pAmor2T self, SConnection *pCon, float fNew)
|
static int CalculateAMORE(pAmor2T self, SConnection *pCon, float fNew)
|
||||||
{
|
{
|
||||||
float fMOM, fSOM, fSTZ, fSOZ;
|
float fMOM, fSOM, fSTZ, fSOZ, fAOM, fAOZ, fC3Z, fconstAOM;
|
||||||
double fAngle, fX, fZ, fBase, fPIR;
|
double fAngle, fX, fZ, fZ2, fBase, fPIR;
|
||||||
float fCOZ, fCOX, fCOM;
|
float fCOZ, fCOX, fCOM;
|
||||||
int iRet;
|
int iRet;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -109,7 +131,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* calculate base height of sample table */
|
/* calculate base height of sample table */
|
||||||
fBase = fSTZ + fSOZ + ObVal(self->aParameter,PARDH);
|
fBase = fSOZ + ObVal(self->aParameter,PARDH);
|
||||||
fPIR = 180. / 3.1415926;
|
fPIR = 180. / 3.1415926;
|
||||||
|
|
||||||
/* calculation for detector */
|
/* calculation for detector */
|
||||||
@ -157,7 +179,129 @@
|
|||||||
self->toStart[4].fTarget);
|
self->toStart[4].fTarget);
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(ObVal(self->aParameter,ANAFLAG) > 0)
|
||||||
|
{
|
||||||
|
/* the analyzer height */
|
||||||
|
fZ = ObVal(self->aParameter,PARADIS)*sin(fAngle);
|
||||||
|
fAOZ = fBase + fZ - ObVal(self->aParameter,PARANA);
|
||||||
|
self->toStart[5].pMot = self->aEngine[MOTAOZ];
|
||||||
|
strcpy(self->toStart[5].pName,self->aEngine[MOTAOZ]->name);
|
||||||
|
self->toStart[5].fTarget = fAOZ;
|
||||||
|
self->iStart = 6;
|
||||||
|
|
||||||
|
/* analyzer omega */
|
||||||
|
self->toStart[6].pMot = self->aEngine[MOTAOM];
|
||||||
|
strcpy(self->toStart[6].pName,self->aEngine[MOTAOM]->name);
|
||||||
|
self->toStart[6].fTarget = fNew/2.
|
||||||
|
+ ObVal(self->aParameter,PARAOM);
|
||||||
|
self->iStart = 7;
|
||||||
|
|
||||||
|
/* C3Z */
|
||||||
|
fZ2 = (ObVal(self->aParameter,PARDS) - ObVal(self->aParameter,
|
||||||
|
PARADIS))*sin(fAngle + (fNew/fPIR) );
|
||||||
|
|
||||||
|
self->toStart[7].pMot = self->aEngine[MOTC3Z];
|
||||||
|
strcpy(self->toStart[7].pName,self->aEngine[MOTC3Z]->name);
|
||||||
|
self->toStart[7].fTarget = fBase + fZ + fZ2 -
|
||||||
|
ObVal(self->aParameter,PARDDD) -
|
||||||
|
self->toStart[1].fTarget;
|
||||||
|
self->iStart = 8;
|
||||||
|
#ifdef DEBUG
|
||||||
|
sprintf(pBueffel,"2T AOZ AOM C3Z");
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
sprintf(pBueffel,"%6.2f %6.2f %6.2f %6.2f",
|
||||||
|
fNew, self->toStart[5].fTarget, self->toStart[6].fTarget,
|
||||||
|
self->toStart[7].fTarget);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*=======================================================================
|
||||||
|
Calculations for Analyzer two theta
|
||||||
|
=========================================================================*/
|
||||||
|
static int CalculateANA2T(pAmor2T self, SConnection *pCon, float fNew)
|
||||||
|
{
|
||||||
|
double fBase, fPIR;
|
||||||
|
float fAOZ, fIncident, fSOM, fMOM, fDiffracted, fDistance, fX, fZ;
|
||||||
|
int iRet;
|
||||||
|
#ifdef DEBUG
|
||||||
|
char pBueffel[132];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* calculate base height of analyzer table */
|
||||||
|
iRet = MotorGetSoftPosition(self->aEngine[MOTSOZ],pCon,&fAOZ);
|
||||||
|
if(iRet != 1)
|
||||||
|
{
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
fBase = fAOZ + ObVal(self->aParameter,PARANA);
|
||||||
|
fPIR = 180. / 3.1415926;
|
||||||
|
|
||||||
|
/* Calculate the incident angle at the analyzer */
|
||||||
|
iRet = MotorGetSoftPosition(self->aEngine[MOTSOM],pCon,&fSOM);
|
||||||
|
if(iRet != 1)
|
||||||
|
{
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
iRet = MotorGetSoftPosition(self->aEngine[MOTMOM],pCon,&fMOM);
|
||||||
|
if(iRet != 1)
|
||||||
|
{
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
fIncident = fMOM + 2. * fSOM;
|
||||||
|
|
||||||
|
/* calculate the angle of the diffracted beam against the
|
||||||
|
horizon at the analyzer.
|
||||||
|
|
||||||
|
fDiffracted = fIncident - 2. * AOM.
|
||||||
|
|
||||||
|
There is a problem here. We should read AOM in order to get the
|
||||||
|
value. However in the context of an omega - two-theta scan on AOM
|
||||||
|
and ana2t, it is fNew.
|
||||||
|
*/
|
||||||
|
fDiffracted = fIncident - fNew;
|
||||||
|
|
||||||
|
|
||||||
|
/* calculation for detector */
|
||||||
|
fDiffracted /= fPIR;
|
||||||
|
fDistance = ObVal(self->aParameter,PARDS) -
|
||||||
|
ObVal(self->aParameter, PARANA);
|
||||||
|
fX = fDistance*cos(fDiffracted);
|
||||||
|
fZ = fDistance*sin(fDiffracted);
|
||||||
|
self->toStart[0].pMot = self->aEngine[MOTCOX];
|
||||||
|
strcpy(self->toStart[0].pName,self->aEngine[MOTCOX]->name);
|
||||||
|
self->toStart[0].fTarget = fX - fDistance;
|
||||||
|
|
||||||
|
self->toStart[1].pMot = self->aEngine[MOTCOZ];
|
||||||
|
strcpy(self->toStart[1].pName,self->aEngine[MOTCOZ]->name);
|
||||||
|
self->toStart[1].fTarget = fZ + fBase -
|
||||||
|
ObVal(self->aParameter,PARDDH);
|
||||||
|
|
||||||
|
self->toStart[2].pMot = self->aEngine[MOTCOM];
|
||||||
|
strcpy(self->toStart[2].pName,self->aEngine[MOTCOM]->name);
|
||||||
|
self->toStart[2].fTarget = -fDiffracted*fPIR;
|
||||||
|
self->iStart = 3;
|
||||||
|
|
||||||
|
/* calculation for diaphragm 5 */
|
||||||
|
fZ = ObVal(self->aParameter,PARDD5) * sin(fDiffracted);
|
||||||
|
self->toStart[3].pMot = self->aEngine[MOTD5B];
|
||||||
|
strcpy(self->toStart[3].pName,self->aEngine[MOTD5B]->name);
|
||||||
|
self->toStart[3].fTarget = fBase + fZ -
|
||||||
|
ObVal(self->aParameter,PARD5H);
|
||||||
|
self->iStart = 4;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
sprintf(pBueffel,"2T COX COZ COM D5B ");
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
sprintf(pBueffel,"%6.2f %6.2f %6.2f %6.2f %6.2f ",
|
||||||
|
fNew, self->toStart[0].fTarget, self->toStart[1].fTarget,
|
||||||
|
self->toStart[2].fTarget,self->toStart[3].fTarget);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*========================================================================
|
/*========================================================================
|
||||||
@ -178,6 +322,39 @@
|
|||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* start them all */
|
||||||
|
for(i = 0; i < self->iStart; i++)
|
||||||
|
{
|
||||||
|
pDriv = self->toStart[i].pMot->pDescriptor->GetInterface(
|
||||||
|
self->toStart[i].pMot,DRIVEID);
|
||||||
|
if(pDriv != NULL)
|
||||||
|
{
|
||||||
|
iRet = pDriv->SetValue(self->toStart[i].pMot,pCon,
|
||||||
|
self->toStart[i].fTarget);
|
||||||
|
if(iRet != OKOK)
|
||||||
|
{
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OKOK;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
static long ANA2TSetValue(void *pData, SConnection *pCon, float fNew)
|
||||||
|
{
|
||||||
|
int i, iRet;
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
pAmor2T self = (pAmor2T) pData;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
/* calculation */
|
||||||
|
iRet = CalculateANA2T(self,pCon,fNew);
|
||||||
|
if(iRet != 1)
|
||||||
|
{
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
/* start them all */
|
/* start them all */
|
||||||
for(i = 0; i < self->iStart; i++)
|
for(i = 0; i < self->iStart; i++)
|
||||||
{
|
{
|
||||||
@ -237,6 +414,45 @@
|
|||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check them all */
|
||||||
|
for(i = 0; i < self->iStart; i++)
|
||||||
|
{
|
||||||
|
pDriv = self->toStart[i].pMot->pDescriptor->GetInterface(
|
||||||
|
self->toStart[i].pMot,DRIVEID);
|
||||||
|
if(pDriv != NULL)
|
||||||
|
{
|
||||||
|
iRet = pDriv->CheckLimits(self->toStart[i].pMot,
|
||||||
|
self->toStart[i].fTarget,
|
||||||
|
error,iErrLen);
|
||||||
|
if(iRet != 1)
|
||||||
|
{
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static int ANA2TCheck(void *pData, float fNew, char *error, int iErrLen)
|
||||||
|
{
|
||||||
|
int i, iRet;
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
pAmor2T self = (pAmor2T) pData;
|
||||||
|
SConnection *pDumCon = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
pDumCon = SCCreateDummyConnection(pServ->pSics);
|
||||||
|
assert(pDumCon);
|
||||||
|
|
||||||
|
/* calculation */
|
||||||
|
iRet = CalculateANA2T(self,pDumCon,fNew);
|
||||||
|
SCDeleteConnection(pDumCon);
|
||||||
|
if(iRet != 1)
|
||||||
|
{
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
/* check them all */
|
/* check them all */
|
||||||
for(i = 0; i < self->iStart; i++)
|
for(i = 0; i < self->iStart; i++)
|
||||||
{
|
{
|
||||||
@ -317,6 +533,31 @@
|
|||||||
fResult = fVal + 2*fMOM;
|
fResult = fVal + 2*fMOM;
|
||||||
return fResult;
|
return fResult;
|
||||||
}
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static float ANA2TGetValue(void *pData, SConnection *pCon)
|
||||||
|
{
|
||||||
|
float fVal, fMOM, fResult;
|
||||||
|
int iRet;
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
pAmor2T self = (pAmor2T) pData;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
/* get AOM */
|
||||||
|
pDriv = self->aEngine[MOTAOM]->pDescriptor->GetInterface(
|
||||||
|
self->aEngine[MOTAOM],DRIVEID);
|
||||||
|
if(pDriv)
|
||||||
|
{
|
||||||
|
fVal = pDriv->GetValue(self->aEngine[MOTAOM],pCon);
|
||||||
|
if(fVal < -9000)
|
||||||
|
{
|
||||||
|
return fVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2. * fVal;
|
||||||
|
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static void *A2TGetInterface(void *pData, int iID)
|
static void *A2TGetInterface(void *pData, int iID)
|
||||||
{
|
{
|
||||||
@ -345,9 +586,65 @@
|
|||||||
fprintf(fd,"%s detectorh %f \n", name, ObVal(self->aParameter,PARDDH));
|
fprintf(fd,"%s detectorh %f \n", name, ObVal(self->aParameter,PARDDH));
|
||||||
fprintf(fd,"%s d4h %f \n", name, ObVal(self->aParameter,PARD4H));
|
fprintf(fd,"%s d4h %f \n", name, ObVal(self->aParameter,PARD4H));
|
||||||
fprintf(fd,"%s d5h %f \n", name, ObVal(self->aParameter,PARD5H));
|
fprintf(fd,"%s d5h %f \n", name, ObVal(self->aParameter,PARD5H));
|
||||||
|
fprintf(fd,"%s anah %f \n", name, ObVal(self->aParameter,PARANA));
|
||||||
|
fprintf(fd,"%s anad %f \n", name, ObVal(self->aParameter,PARADIS));
|
||||||
|
fprintf(fd,"%s anaflag %f \n", name, ObVal(self->aParameter,ANAFLAG));
|
||||||
|
fprintf(fd,"%s c2h %f \n", name, ObVal(self->aParameter,PARDDD));
|
||||||
|
fprintf(fd,"%s aomconst %f \n", name, ObVal(self->aParameter,PARAOM));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static void A2TList(pAmor2T self, SConnection *pCon, char *name)
|
||||||
|
{
|
||||||
|
char pBueffel[132];
|
||||||
|
Tcl_DString tString;
|
||||||
|
|
||||||
|
assert(pCon);
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
Tcl_DStringInit(&tString);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.detectord %f \n", name, ObVal(self->aParameter,PARDS));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.sampleh %f \n", name, ObVal(self->aParameter,PARDH));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.d4d %f \n", name, ObVal(self->aParameter,PARDD4));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.d5d %f \n", name, ObVal(self->aParameter,PARDD5));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.interrupt %f \n", name, ObVal(self->aParameter,PARINT));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.detectorh %f \n", name, ObVal(self->aParameter,PARDDH));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.d4h %f \n", name, ObVal(self->aParameter,PARD4H));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.d5h %f \n", name, ObVal(self->aParameter,PARD5H));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.anah %f \n", name, ObVal(self->aParameter,PARANA));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.anad %f \n", name, ObVal(self->aParameter,PARADIS));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.anaflag %f \n", name, ObVal(self->aParameter,ANAFLAG));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.c2h %f \n", name, ObVal(self->aParameter,PARDDD));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"%s.aomconst %f \n", name, ObVal(self->aParameter,PARAOM));
|
||||||
|
Tcl_DStringAppend(&tString,pBueffel,-1);
|
||||||
|
SCWrite(pCon,Tcl_DStringValue(&tString),eValue);
|
||||||
|
Tcl_DStringFree(&tString);
|
||||||
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
static void A2TKill(void *pData)
|
static void A2TKill(void *pData)
|
||||||
{
|
{
|
||||||
@ -375,12 +672,12 @@
|
|||||||
int Amor2TFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int Amor2TFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
pAmor2T pNew = NULL;
|
pAmor2T pNew, pAOM = NULL;
|
||||||
int i, iRet;
|
int i, iRet;
|
||||||
char pBueffel[512];
|
char pBueffel[512];
|
||||||
char *pMot = NULL;
|
char *pMot = NULL;
|
||||||
|
|
||||||
if(argc < 3)
|
if(argc < 4)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,
|
SCWrite(pCon,
|
||||||
"ERROR: Insufficient number of arguments to Amor2tFactory",
|
"ERROR: Insufficient number of arguments to Amor2tFactory",
|
||||||
@ -418,6 +715,7 @@
|
|||||||
if(!pNew->aEngine[MOTMOM])
|
if(!pNew->aEngine[MOTMOM])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -433,6 +731,7 @@
|
|||||||
if(!pNew->aEngine[MOTSOM])
|
if(!pNew->aEngine[MOTSOM])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -448,6 +747,7 @@
|
|||||||
if(!pNew->aEngine[MOTCOZ])
|
if(!pNew->aEngine[MOTCOZ])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -463,6 +763,7 @@
|
|||||||
if(!pNew->aEngine[MOTCOX])
|
if(!pNew->aEngine[MOTCOX])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -478,6 +779,7 @@
|
|||||||
if(!pNew->aEngine[MOTSTZ])
|
if(!pNew->aEngine[MOTSTZ])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -493,6 +795,7 @@
|
|||||||
if(!pNew->aEngine[MOTSOZ])
|
if(!pNew->aEngine[MOTSOZ])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -508,6 +811,7 @@
|
|||||||
if(!pNew->aEngine[MOTD4B])
|
if(!pNew->aEngine[MOTD4B])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -523,6 +827,7 @@
|
|||||||
if(!pNew->aEngine[MOTD5B])
|
if(!pNew->aEngine[MOTD5B])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -538,12 +843,62 @@
|
|||||||
if(!pNew->aEngine[MOTCOM])
|
if(!pNew->aEngine[MOTCOM])
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"aoz",TCL_GLOBAL_ONLY);
|
||||||
|
if(!pMot)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: no value for aoz motor found",eError);
|
||||||
|
A2TKill(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pNew->aEngine[MOTAOZ] = FindMotor(pSics,pMot);
|
||||||
|
if(!pNew->aEngine[MOTAOZ])
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
A2TKill(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"aom",TCL_GLOBAL_ONLY);
|
||||||
|
if(!pMot)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: no value for aom motor found",eError);
|
||||||
|
A2TKill(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pNew->aEngine[MOTAOM] = FindMotor(pSics,pMot);
|
||||||
|
if(!pNew->aEngine[MOTAOM])
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
A2TKill(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMot = Tcl_GetVar2(pSics->pTcl,argv[2],"c3z",TCL_GLOBAL_ONLY);
|
||||||
|
if(!pMot)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: no value for c3z motor found",eError);
|
||||||
|
A2TKill(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pNew->aEngine[MOTC3Z] = FindMotor(pSics,pMot);
|
||||||
|
if(!pNew->aEngine[MOTC3Z])
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: motor %s NOT found!", pMot);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
A2TKill(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* initialize parameters */
|
/* initialize parameters */
|
||||||
ObParInit(pNew->aParameter,PARDS,"detectord",400.,usMugger);
|
ObParInit(pNew->aParameter,PARDS,"detectord",1400.,usMugger);
|
||||||
ObParInit(pNew->aParameter,PARDH,"sampleh",50.,usMugger);
|
ObParInit(pNew->aParameter,PARDH,"sampleh",50.,usMugger);
|
||||||
ObParInit(pNew->aParameter,PARDD4,"d4d",100.,usMugger);
|
ObParInit(pNew->aParameter,PARDD4,"d4d",100.,usMugger);
|
||||||
ObParInit(pNew->aParameter,PARDD5,"d5d",200.,usMugger);
|
ObParInit(pNew->aParameter,PARDD5,"d5d",200.,usMugger);
|
||||||
@ -551,6 +906,12 @@
|
|||||||
ObParInit(pNew->aParameter,PARDDH,"detectorh",40.,usMugger);
|
ObParInit(pNew->aParameter,PARDDH,"detectorh",40.,usMugger);
|
||||||
ObParInit(pNew->aParameter,PARD4H,"d4h",40.,usMugger);
|
ObParInit(pNew->aParameter,PARD4H,"d4h",40.,usMugger);
|
||||||
ObParInit(pNew->aParameter,PARD5H,"d5h",400.,usMugger);
|
ObParInit(pNew->aParameter,PARD5H,"d5h",400.,usMugger);
|
||||||
|
ObParInit(pNew->aParameter,PARANA,"anah",400.,usMugger);
|
||||||
|
ObParInit(pNew->aParameter,PARADIS,"anad",600.,usMugger);
|
||||||
|
ObParInit(pNew->aParameter,ANAFLAG,"anaflag",-1.,usMugger);
|
||||||
|
ObParInit(pNew->aParameter,PARDDD,"c2h",100.,usMugger);
|
||||||
|
ObParInit(pNew->aParameter,PARAOM,"aomconst",3.,usMugger);
|
||||||
|
|
||||||
|
|
||||||
/* initialize interfaces */
|
/* initialize interfaces */
|
||||||
pNew->pDes->GetInterface = A2TGetInterface;
|
pNew->pDes->GetInterface = A2TGetInterface;
|
||||||
@ -561,7 +922,24 @@
|
|||||||
pNew->pDriv->CheckStatus = A2TStatus;
|
pNew->pDriv->CheckStatus = A2TStatus;
|
||||||
pNew->pDriv->GetValue = A2TGetValue;
|
pNew->pDriv->GetValue = A2TGetValue;
|
||||||
|
|
||||||
/* install command */
|
/* copy data structure for second command for aom2t */
|
||||||
|
pAOM = (pAmor2T)malloc(sizeof(Amor2T));
|
||||||
|
if(!pAOM)
|
||||||
|
{
|
||||||
|
A2TKill(pNew);
|
||||||
|
SCWrite(pCon,"ERROR: out of memory in Amor2TFactory",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(pAOM,pNew,sizeof(Amor2T));
|
||||||
|
|
||||||
|
/* set modified interface functions */
|
||||||
|
pAOM->pDes->SaveStatus = NULL;
|
||||||
|
pAOM->pDriv->CheckLimits = ANA2TCheck;
|
||||||
|
pAOM->pDriv->SetValue = ANA2TSetValue;
|
||||||
|
pAOM->pDriv->GetValue = ANA2TGetValue;
|
||||||
|
|
||||||
|
|
||||||
|
/* install commands */
|
||||||
iRet = AddCommand(pSics,argv[1],
|
iRet = AddCommand(pSics,argv[1],
|
||||||
Amor2TAction,A2TKill,pNew);
|
Amor2TAction,A2TKill,pNew);
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
@ -572,6 +950,16 @@
|
|||||||
A2TKill(pNew);
|
A2TKill(pNew);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
iRet = AddCommand(pSics,argv[3],
|
||||||
|
Amor2TAction,free,pAOM);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: duplicate command %s NOT created",
|
||||||
|
argv[1]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
A2TKill(pNew);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
@ -590,6 +978,13 @@
|
|||||||
if(argc > 1)
|
if(argc > 1)
|
||||||
{
|
{
|
||||||
strtolower(argv[1]);
|
strtolower(argv[1]);
|
||||||
|
/* deal with list */
|
||||||
|
if(strcmp(argv[1],"list") == 0)
|
||||||
|
{
|
||||||
|
A2TList(self,pCon,argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* otherwise it should be a parameter command */
|
||||||
if(argc >= 3)
|
if(argc >= 3)
|
||||||
{
|
{
|
||||||
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
|
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
|
||||||
|
4
amor2t.w
4
amor2t.w
@ -10,7 +10,7 @@ This object implements this complex movement as a virtual motor.
|
|||||||
|
|
||||||
The following formulas are used for the necessary calculations:
|
The following formulas are used for the necessary calculations:
|
||||||
\begin{eqnarray}
|
\begin{eqnarray}
|
||||||
delta height & = & h_{s} - R \sin \alpha \\
|
delta height & = & h_{s} - \sin \alpha \\
|
||||||
delta x & = & |x_{c} - x_{s}| - R \cos \alpha \\
|
delta x & = & |x_{c} - x_{s}| - R \cos \alpha \\
|
||||||
omega & = & -2 MOM + 2 SOM \\
|
omega & = & -2 MOM + 2 SOM \\
|
||||||
\end{eqnarray}
|
\end{eqnarray}
|
||||||
@ -18,7 +18,7 @@ with
|
|||||||
\begin{eqnarray}
|
\begin{eqnarray}
|
||||||
h_{s} & = & \tan(2MOM)|x_{c} - x_{s}| \\
|
h_{s} & = & \tan(2MOM)|x_{c} - x_{s}| \\
|
||||||
R & = & \sqrt{hs^{2} - |x_{c} - x_{s}|^{2}} \\
|
R & = & \sqrt{hs^{2} - |x_{c} - x_{s}|^{2}} \\
|
||||||
\alpha & = & 180 -90 - \beta - 2SOM \\
|
\alpha & = & ATT - 2SOM \\
|
||||||
\beta & = & 180 - 90 - 2MOM \\
|
\beta & = & 180 - 90 - 2MOM \\
|
||||||
MOM & = & polarizer \omega \\
|
MOM & = & polarizer \omega \\
|
||||||
SOM & = & sample \omega \\
|
SOM & = & sample \omega \\
|
||||||
|
@ -135,7 +135,7 @@
|
|||||||
SCWriteUUencoded(pCon,"arrow_spinupup",iData,
|
SCWriteUUencoded(pCon,"arrow_spinupup",iData,
|
||||||
(iLength+1)*sizeof(int));
|
(iLength+1)*sizeof(int));
|
||||||
/* send counts for other detector */
|
/* send counts for other detector */
|
||||||
GetScanMonitor(pScan,0,lData,iLength);
|
GetScanMonitor(pScan,2,lData,iLength);
|
||||||
for(i = 0 ; i < iLength; i++)
|
for(i = 0 ; i < iLength; i++)
|
||||||
{
|
{
|
||||||
iData[i+1] = htonl((int)(lData[i]));
|
iData[i+1] = htonl((int)(lData[i]));
|
||||||
|
@ -248,7 +248,10 @@ set a2t(soz) soz
|
|||||||
set a2t(d4b) d4b
|
set a2t(d4b) d4b
|
||||||
set a2t(d5b) d5b
|
set a2t(d5b) d5b
|
||||||
set a2t(com) com
|
set a2t(com) com
|
||||||
MakeAmor2T a2t a2t
|
set a2t(aom) aom
|
||||||
|
set a2t(aoz) aoz
|
||||||
|
set a2t(c3z) c3z
|
||||||
|
MakeAmor2T a2t a2t aom2t
|
||||||
|
|
||||||
#=========== Status Display Support
|
#=========== Status Display Support
|
||||||
MakeAmorStatus amorstatus xxxscan hm
|
MakeAmorStatus amorstatus xxxscan hm
|
||||||
|
@ -459,6 +459,7 @@
|
|||||||
case EL737__BAD_TMO:
|
case EL737__BAD_TMO:
|
||||||
case EL737__BAD_REPLY:
|
case EL737__BAD_REPLY:
|
||||||
case EL737__BAD_SNTX:
|
case EL737__BAD_SNTX:
|
||||||
|
case EL737__BAD_OVFL:
|
||||||
return COREDO;
|
return COREDO;
|
||||||
break;
|
break;
|
||||||
case EL737__BAD_LOC:
|
case EL737__BAD_LOC:
|
||||||
|
@ -917,7 +917,7 @@
|
|||||||
if(iRet)
|
if(iRet)
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"%s.%s = %f",self->pName,"CurrentValue", fPos);
|
sprintf(pBueffel,"%s.%s = %f",self->pName,"CurrentValue", fPos);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -955,6 +955,10 @@
|
|||||||
iRet = Tcl_GetDouble(pSics->pTcl,argv[1],&dVal);
|
iRet = Tcl_GetDouble(pSics->pTcl,argv[1],&dVal);
|
||||||
if(iRet == TCL_OK) /* float Value: drive */
|
if(iRet == TCL_OK) /* float Value: drive */
|
||||||
{
|
{
|
||||||
|
if(!SCMatchRights(pCon,usUser))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
iRet = EVCDrive(self,pCon,(float)dVal);
|
iRet = EVCDrive(self,pCon,(float)dVal);
|
||||||
if(iRet)
|
if(iRet)
|
||||||
{
|
{
|
||||||
|
11
hklscan.c
11
hklscan.c
@ -134,7 +134,16 @@
|
|||||||
|
|
||||||
assert(self->pCon);
|
assert(self->pCon);
|
||||||
assert(self->pSics);
|
assert(self->pSics);
|
||||||
assert(self->fd);
|
|
||||||
|
if(!self->fd)
|
||||||
|
{
|
||||||
|
self->fd = fopen(self->pFile,"r+");
|
||||||
|
if(!self->fd)
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,"ERROR: failed to reopen scan file during scan",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* jump to end of header */
|
/* jump to end of header */
|
||||||
fseek(self->fd,self->lPos, SEEK_SET);
|
fseek(self->fd,self->lPos, SEEK_SET);
|
||||||
|
42
nserver.c
42
nserver.c
@ -6,13 +6,20 @@
|
|||||||
|
|
||||||
Mark Koennecke, October 1996
|
Mark Koennecke, October 1996
|
||||||
Revised for use with tasker: Mark Koennecke, September 1997
|
Revised for use with tasker: Mark Koennecke, September 1997
|
||||||
|
|
||||||
|
Added code to redirect stdout/sterr to file.
|
||||||
|
|
||||||
|
Mark Koennecke, May 2000
|
||||||
|
|
||||||
Copyright: see copyright.h
|
Copyright: see copyright.h
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#define NEEDDINTINIT
|
#define NEEDDINTINIT
|
||||||
#include "fortify.h"
|
#include "fortify.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "conman.h"
|
#include "conman.h"
|
||||||
#include "SCinter.h"
|
#include "SCinter.h"
|
||||||
@ -75,7 +82,8 @@
|
|||||||
pNetRead pReader = NULL;
|
pNetRead pReader = NULL;
|
||||||
pPerfMon pMon = NULL;
|
pPerfMon pMon = NULL;
|
||||||
CommandList *pCom;
|
CommandList *pCom;
|
||||||
|
pid_t myPid;
|
||||||
|
|
||||||
/* allocate a new server structure */
|
/* allocate a new server structure */
|
||||||
self = (pServer)malloc(sizeof(SicsServer));
|
self = (pServer)malloc(sizeof(SicsServer));
|
||||||
if(!self)
|
if(!self)
|
||||||
@ -86,6 +94,7 @@
|
|||||||
memset(self,0,sizeof(SicsServer));
|
memset(self,0,sizeof(SicsServer));
|
||||||
*pServ = self;
|
*pServ = self;
|
||||||
|
|
||||||
|
|
||||||
/* configure fortify */
|
/* configure fortify */
|
||||||
iFortifyScope = Fortify_EnterScope();
|
iFortifyScope = Fortify_EnterScope();
|
||||||
Fortify_CheckAllMemory();
|
Fortify_CheckAllMemory();
|
||||||
@ -119,7 +128,28 @@
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
check for option RedirectFile and redirect stout/sterr to it
|
||||||
|
if present.
|
||||||
|
*/
|
||||||
|
pPtr = NULL;
|
||||||
|
pPtr = IFindOption(pSICSOptions,"RedirectFile");
|
||||||
|
if(pPtr != NULL)
|
||||||
|
{
|
||||||
|
myPid = getpid();
|
||||||
|
sprintf(pBueffel,"%s%5.5d.log",pPtr,(int)myPid);
|
||||||
|
fp = freopen(pBueffel,"w",stdout);
|
||||||
|
if(!fp)
|
||||||
|
{
|
||||||
|
printf("Failed to redirect stdout/stderr to %s\n",pBueffel);
|
||||||
|
}
|
||||||
|
fp = freopen(pBueffel,"w",stderr);
|
||||||
|
if(!fp)
|
||||||
|
{
|
||||||
|
printf("Failed to redirect stdout/stderr to %s\n",pBueffel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* initialise net reader */
|
/* initialise net reader */
|
||||||
pPtr = NULL;
|
pPtr = NULL;
|
||||||
@ -294,6 +324,14 @@
|
|||||||
{
|
{
|
||||||
printf("ERROR: Cannot allocate dummy connection, status NOT saved");
|
printf("ERROR: Cannot allocate dummy connection, status NOT saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* close redirection file if present */
|
||||||
|
pText = NULL;
|
||||||
|
pText = IFindOption(pSICSOptions,"RedirectFile");
|
||||||
|
if(pText)
|
||||||
|
{
|
||||||
|
fclose(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
/* clean out */
|
/* clean out */
|
||||||
if(pSICSOptions)
|
if(pSICSOptions)
|
||||||
|
2
ofac.c
2
ofac.c
@ -295,9 +295,7 @@
|
|||||||
RemoveCommand(pSics,"MakeRuenBuffer");
|
RemoveCommand(pSics,"MakeRuenBuffer");
|
||||||
RemoveCommand(pSics,"MakeScan");
|
RemoveCommand(pSics,"MakeScan");
|
||||||
RemoveCommand(pSics,"MakeO2T");
|
RemoveCommand(pSics,"MakeO2T");
|
||||||
/*
|
|
||||||
RemoveCommand(pSics,"SicsAlias");
|
RemoveCommand(pSics,"SicsAlias");
|
||||||
*/
|
|
||||||
RemoveCommand(pSics,"InitDMC");
|
RemoveCommand(pSics,"InitDMC");
|
||||||
RemoveCommand(pSics,"InitSANS");
|
RemoveCommand(pSics,"InitSANS");
|
||||||
RemoveCommand(pSics,"MakeHM");
|
RemoveCommand(pSics,"MakeHM");
|
||||||
|
4
test.tcl
4
test.tcl
@ -12,8 +12,12 @@ rename scan stscan
|
|||||||
#-------- a home for this, everything else is in relation to this
|
#-------- a home for this, everything else is in relation to this
|
||||||
set shome /data/koenneck/src
|
set shome /data/koenneck/src
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# first all the server options are set
|
# first all the server options are set
|
||||||
|
|
||||||
|
ServerOption RedirectFile $shome/sics/stdout
|
||||||
|
|
||||||
ServerOption ReadTimeOut 100
|
ServerOption ReadTimeOut 100
|
||||||
# timeout when checking for commands. In the main loop SICS checks for
|
# timeout when checking for commands. In the main loop SICS checks for
|
||||||
# pending commands on each connection with the above timeout, has
|
# pending commands on each connection with the above timeout, has
|
||||||
|
Reference in New Issue
Block a user