cdev-1.7.2n
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,373 @@
|
||||
service CLIP {
|
||||
tags {server, host, port}
|
||||
}
|
||||
|
||||
|
||||
class ca {
|
||||
verbs {get, set, monitorOn, monitorOff}
|
||||
attributes {
|
||||
VAL CLIP {server=Gateway1, host=devsrv.cebaf.gov, port=9199};
|
||||
XPOS CLIP {server=Gateway1, host=devsrv.cebaf.gov, port=9199};
|
||||
YPOS CLIP {server=Gateway1, host=devsrv.cebaf.gov, port=9199};
|
||||
ServerInfo CLIP {server=Gateway1, host=devsrv.cebaf.gov, port=9199};
|
||||
ClientInfo CLIP {server=Gateway1, host=devsrv.cebaf.gov, port=9199};
|
||||
}
|
||||
}
|
||||
|
||||
class ModelClass
|
||||
{
|
||||
verbs {get, set, monitorOn, monitorOff}
|
||||
attributes {
|
||||
elements CLIP {server=GOLD, host=mdlsrv.cebaf.gov, port=9000};
|
||||
sections CLIP {server=GOLD, host=mdlsrv.cebaf.gov, port=9000};
|
||||
ServerInfo CLIP {server=GOLD, host=mdlsrv.cebaf.gov, port=9000};
|
||||
ClientInfo CLIP {server=GOLD, host=mdlsrv.cebaf.gov, port=9000};
|
||||
}
|
||||
}
|
||||
|
||||
ModelClass : model ;
|
||||
|
||||
ca : IPM1R01
|
||||
IPM1R02
|
||||
IPM1R03
|
||||
IPM1R04
|
||||
IPM1R06
|
||||
IPM1R08
|
||||
IPM1R09
|
||||
IPM1R10
|
||||
IPM1S01
|
||||
IPM1S02
|
||||
IPM1S03
|
||||
IPM1S05
|
||||
IPM1S07
|
||||
IPM1S08
|
||||
IPM1S09
|
||||
IPM1S10
|
||||
IPM2R01
|
||||
IPM2R02
|
||||
IPM2R03
|
||||
IPM2R04
|
||||
IPM2R06
|
||||
IPM2R08
|
||||
IPM2R09
|
||||
IPM2R10
|
||||
IPM2S01
|
||||
IPM2S02
|
||||
IPM2S03
|
||||
IPM2S07
|
||||
IPM2S08
|
||||
IPM2S09
|
||||
IPM2T00A
|
||||
IPM2T00B
|
||||
IPM2T01
|
||||
IPM2T03
|
||||
IPM2T06
|
||||
IPM2T07
|
||||
IPM2T08
|
||||
IPM2T09
|
||||
IPM3A02
|
||||
IPM3A03
|
||||
IPM3A05
|
||||
IPM3A07
|
||||
IPM3A08
|
||||
IPM3A09
|
||||
IPM3A10
|
||||
IPM3A11
|
||||
IPM3A13
|
||||
IPM3A15
|
||||
IPM3A16
|
||||
IPM3A17
|
||||
IPM3A18
|
||||
IPM3A19
|
||||
IPM3A21
|
||||
IPM3A23
|
||||
IPM3A24
|
||||
IPM3A25
|
||||
IPM3A26
|
||||
IPM3A27
|
||||
IPM3A29
|
||||
IPM3A31
|
||||
IPM3A32
|
||||
IPM3E01
|
||||
IPM3E03
|
||||
IPM3R01
|
||||
IPM3R02
|
||||
IPM3R03
|
||||
IPM3R04
|
||||
IPM3R06
|
||||
IPM3R08
|
||||
IPM3R09
|
||||
IPM3R10
|
||||
IPM3S01
|
||||
IPM3S02
|
||||
IPM3S03
|
||||
IPM3S05
|
||||
IPM3S07
|
||||
IPM3S08
|
||||
IPM3S09
|
||||
IPM3S10
|
||||
IPM4A02
|
||||
IPM4A03
|
||||
IPM4A05
|
||||
IPM4A07
|
||||
IPM4A08
|
||||
IPM4A09
|
||||
IPM4A10
|
||||
IPM4A11
|
||||
IPM4A13
|
||||
IPM4A15
|
||||
IPM4A16
|
||||
IPM4A17
|
||||
IPM4A18
|
||||
IPM4A19
|
||||
IPM4A21
|
||||
IPM4A23
|
||||
IPM4A24
|
||||
IPM4A25
|
||||
IPM4A26
|
||||
IPM4A27
|
||||
IPM4A29
|
||||
IPM4A31
|
||||
IPM4A32
|
||||
IPM4E03
|
||||
IPM4R01
|
||||
IPM4R02
|
||||
IPM4R03
|
||||
IPM4R04
|
||||
IPM4R06
|
||||
IPM4R08
|
||||
IPM4R09
|
||||
IPM4R10
|
||||
IPM4S01
|
||||
IPM4S02
|
||||
IPM4S03
|
||||
IPM4S07
|
||||
IPM4S09
|
||||
IPM4T00A
|
||||
IPM4T00B
|
||||
IPM4T01
|
||||
IPM4T03
|
||||
IPM4T06
|
||||
IPM4T07
|
||||
IPM4T08
|
||||
IPM4T09
|
||||
IPM5A02
|
||||
IPM5A03
|
||||
IPM5A05
|
||||
IPM5A07
|
||||
IPM5A08
|
||||
IPM5A09
|
||||
IPM5A10
|
||||
IPM5A11
|
||||
IPM5A13
|
||||
IPM5A15
|
||||
IPM5A16
|
||||
IPM5A17
|
||||
IPM5A18
|
||||
IPM5A19
|
||||
IPM5A21
|
||||
IPM5A23
|
||||
IPM5A24
|
||||
IPM5A25
|
||||
IPM5A26
|
||||
IPM5A27
|
||||
IPM5A29
|
||||
IPM5A31
|
||||
IPM5A32
|
||||
IPM5E01
|
||||
IPM5E03
|
||||
IPM5R01
|
||||
IPM5R02
|
||||
IPM5R03
|
||||
IPM5R04
|
||||
IPM5R06
|
||||
IPM5R08
|
||||
IPM5R09
|
||||
IPM5R10
|
||||
IPM5S01
|
||||
IPM5S02
|
||||
IPM5S03
|
||||
IPM5S05
|
||||
IPM5S07
|
||||
IPM5S08
|
||||
IPM5S09
|
||||
IPM5S10
|
||||
IPM6A02
|
||||
IPM6A03
|
||||
IPM6A05
|
||||
IPM6A07
|
||||
IPM6A08
|
||||
IPM6A09
|
||||
IPM6A10
|
||||
IPM6A11
|
||||
IPM6A13
|
||||
IPM6A15
|
||||
IPM6A16
|
||||
IPM6A17
|
||||
IPM6A18
|
||||
IPM6A19
|
||||
IPM6A21
|
||||
IPM6A23
|
||||
IPM6A24
|
||||
IPM6A25
|
||||
IPM6A26
|
||||
IPM6A27
|
||||
IPM6A29
|
||||
IPM6A31
|
||||
IPM6A32
|
||||
IPM6E03
|
||||
IPM6R01
|
||||
IPM6R02
|
||||
IPM6R03
|
||||
IPM6R04
|
||||
IPM6R06
|
||||
IPM6R08
|
||||
IPM6R09
|
||||
IPM6R10
|
||||
IPM6S01
|
||||
IPM6S02
|
||||
IPM6S03
|
||||
IPM6S07
|
||||
IPM6S09
|
||||
IPM6T00A
|
||||
IPM6T00B
|
||||
IPM6T01
|
||||
IPM6T03
|
||||
IPM6T06
|
||||
IPM6T07
|
||||
IPM6T08
|
||||
IPM6T09
|
||||
IPM7A02
|
||||
IPM7A03
|
||||
IPM7A05
|
||||
IPM7A07
|
||||
IPM7A08
|
||||
IPM7A09
|
||||
IPM7A10
|
||||
IPM7A11
|
||||
IPM7A13
|
||||
IPM7A15
|
||||
IPM7A16
|
||||
IPM7A17
|
||||
IPM7A18
|
||||
IPM7A19
|
||||
IPM7A21
|
||||
IPM7A23
|
||||
IPM7A24
|
||||
IPM7A25
|
||||
IPM7A26
|
||||
IPM7A27
|
||||
IPM7A29
|
||||
IPM7A31
|
||||
IPM7A32
|
||||
IPM7E01
|
||||
IPM7E03
|
||||
IPM7R01
|
||||
IPM7R02
|
||||
IPM7R03
|
||||
IPM7R04
|
||||
IPM7R06
|
||||
IPM7R08
|
||||
IPM7R09
|
||||
IPM7R10
|
||||
IPM7S01
|
||||
IPM7S02
|
||||
IPM7S03
|
||||
IPM7S05
|
||||
IPM7S07
|
||||
IPM7S08
|
||||
IPM7S09
|
||||
IPM7S10
|
||||
IPM8A02
|
||||
IPM8A03
|
||||
IPM8A05
|
||||
IPM8A07
|
||||
IPM8A08
|
||||
IPM8A09
|
||||
IPM8A10
|
||||
IPM8A11
|
||||
IPM8A13
|
||||
IPM8A15
|
||||
IPM8A16
|
||||
IPM8A17
|
||||
IPM8A18
|
||||
IPM8A19
|
||||
IPM8A21
|
||||
IPM8A23
|
||||
IPM8A24
|
||||
IPM8A25
|
||||
IPM8A26
|
||||
IPM8A27
|
||||
IPM8A29
|
||||
IPM8A31
|
||||
IPM8A32
|
||||
IPM8E03
|
||||
IPM8R01
|
||||
IPM8R02
|
||||
IPM8R03
|
||||
IPM8R04
|
||||
IPM8R06
|
||||
IPM8R08
|
||||
IPM8R09
|
||||
IPM8R10
|
||||
IPM8S01
|
||||
IPM8S02
|
||||
IPM8S03
|
||||
IPM8S07
|
||||
IPM8S08
|
||||
IPM8T00A
|
||||
IPM8T00B
|
||||
IPM8T01
|
||||
IPM8T03
|
||||
IPM8T06
|
||||
IPM8T07
|
||||
IPM8T08
|
||||
IPM8T09
|
||||
IPM9A02
|
||||
IPM9A03
|
||||
IPM9A05
|
||||
IPM9A07
|
||||
IPM9A08
|
||||
IPM9A09
|
||||
IPM9A10
|
||||
IPM9A11
|
||||
IPM9A13
|
||||
IPM9A15
|
||||
IPM9A16
|
||||
IPM9A17
|
||||
IPM9A18
|
||||
IPM9A19
|
||||
IPM9A21
|
||||
IPM9A23
|
||||
IPM9A24
|
||||
IPM9A25
|
||||
IPM9A26
|
||||
IPM9A27
|
||||
IPM9A29
|
||||
IPM9A31
|
||||
IPM9A32
|
||||
IPM9E01
|
||||
IPM9E03
|
||||
IPM9R01
|
||||
IPM9R02
|
||||
IPM9R03
|
||||
IPM9R04
|
||||
IPM9R05
|
||||
IPM9R07
|
||||
IPM9R08
|
||||
IPM9S01
|
||||
IPM9S02
|
||||
IPM9S04
|
||||
IPM9S05
|
||||
IPM9S06
|
||||
IPM9S07
|
||||
IPM9S08
|
||||
IPMAS00
|
||||
IPMAT02
|
||||
IPMAT07
|
||||
IPMAT09
|
||||
IPMNS01
|
||||
IPMNS04
|
||||
IPMNS05
|
||||
IPMNS06
|
||||
;
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <cdevSystem.h>
|
||||
#include <cdevDirectory.h>
|
||||
#include <CLIPService.h>
|
||||
#include <CLIPRequestObject.h>
|
||||
|
||||
CLIPRequestObject::CLIPRequestObject ( char * device, char * message, cdevSystem & system)
|
||||
: cdevClientRequestObject(device, message, system)
|
||||
{
|
||||
cdevData output;
|
||||
|
||||
*host = 0;
|
||||
port = 0;
|
||||
|
||||
sprintf (host, "resolveServiceData %s %s", device, message);
|
||||
if((system.nameServer()).send(host, NULL, &output)==CDEV_SUCCESS)
|
||||
{
|
||||
*host = 0;
|
||||
output.get ("host", host, 256);
|
||||
output.get ("port", &port);
|
||||
}
|
||||
else *host = 0;
|
||||
}
|
||||
|
||||
int CLIPRequestObject::getServerHandler ( ServerHandler ** Handler )
|
||||
{
|
||||
CLIPService * svc = (CLIPService *)service_;
|
||||
int result = CDEV_SUCCESS;
|
||||
|
||||
*Handler = NULL;
|
||||
|
||||
if (*server==0 && *DDL_server!=0) strcpy(server, DDL_server);
|
||||
if (*server!=0 && handler==NULL)
|
||||
{
|
||||
if((*Handler = svc->connect(server,
|
||||
(*host)?host:(char *)NULL,
|
||||
(*host)?port:0))==NULL) result = CDEV_ERROR;
|
||||
else
|
||||
{
|
||||
handler = *Handler;
|
||||
handler->registerServerCallback(this);
|
||||
}
|
||||
}
|
||||
else *Handler = handler;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <cdevClientRequestObject.h>
|
||||
|
||||
class CLIPRequestObject : public cdevClientRequestObject
|
||||
{
|
||||
protected:
|
||||
char host [256];
|
||||
unsigned short port;
|
||||
|
||||
public:
|
||||
CLIPRequestObject ( char *device, char * message,
|
||||
cdevSystem & system = cdevSystem::defaultSystem());
|
||||
|
||||
virtual int getServerHandler ( ServerHandler ** Handler );
|
||||
};
|
||||
@@ -0,0 +1,247 @@
|
||||
#include <CLIPService.h>
|
||||
#include <CLIPRequestObject.h>
|
||||
#include <cdevMessage.h>
|
||||
|
||||
// *****************************************************************************
|
||||
// * newCLIPService:
|
||||
// * This function will be called by the cdevSystem object to create an
|
||||
// * initial instance of the CLIPService.
|
||||
// *****************************************************************************
|
||||
extern "C" cdevService * newCLIPService (char * name, cdevSystem * system)
|
||||
{
|
||||
return new CLIPService(name, *system);
|
||||
}
|
||||
|
||||
void NULLError (int, char *, cdevRequestObject *)
|
||||
{
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * CLIPService::CLIPService :
|
||||
// * This is the constructor for the CLIPService. It initializes the
|
||||
// * underlying CLIPService by specifying that it is in the domain of
|
||||
// * VIRTUAL.
|
||||
// *****************************************************************************
|
||||
CLIPService::CLIPService ( char * name, cdevSystem & system)
|
||||
: cdevClientService("CLIP", name, system)
|
||||
{
|
||||
system.reportError(CDEV_SEVERITY_INFO, "CLIPService", NULL,
|
||||
"Constructing a new CLIPService");
|
||||
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * CLIPService::getRequestObject :
|
||||
// * This is the interface that cdev objects will use to obtain a
|
||||
// * CLIPRequestObject object. The CLIPRequestObject
|
||||
// * represents a combined device and message pair that is associated
|
||||
// * with the CLIPService.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int CLIPService::getRequestObject ( char * device, char * message, cdevRequestObject * &req)
|
||||
{
|
||||
req = new CLIPRequestObject (device, message, system_);
|
||||
return (req ? CDEV_SUCCESS : CDEV_ERROR);
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * CLIPService::connect :
|
||||
// * This mechanism will establish a new connection with a server and will
|
||||
// * will return a pointer to the ServerHandler. If the host and port are
|
||||
// * specified in the arguments, then the method will attempt to connect
|
||||
// * using those values without going through the CDEV Name Server.
|
||||
// *
|
||||
// * Note: This method will insert the ServerHandler into the connections
|
||||
// * object and will install it in the Reactor.
|
||||
// *****************************************************************************
|
||||
ServerHandler * CLIPService::connect ( char * server, char * host, short port )
|
||||
{
|
||||
ServerHandler * handler = NULL;
|
||||
|
||||
// *********************************************************************
|
||||
// * First attempt to locate the handler from the existing connections.
|
||||
// *********************************************************************
|
||||
if(server && *server && (handler = connections.find(server))==NULL)
|
||||
{
|
||||
int errCode = CDEV_SUCCESS;
|
||||
char serverHost[255];
|
||||
short serverPort;
|
||||
int serverStatus;
|
||||
int hostMatchesNS;
|
||||
|
||||
// *************************************************************
|
||||
// * Initialize these values to reflect a server that is not
|
||||
// * defined within the name server.
|
||||
// *************************************************************
|
||||
*serverHost = 0;
|
||||
serverPort = 0;
|
||||
serverStatus = 2;
|
||||
hostMatchesNS = 0;
|
||||
|
||||
// *************************************************************
|
||||
// * Raise the error threshold to reduce noise while the service
|
||||
// * tries to resolve the location of the server.
|
||||
// *************************************************************
|
||||
system_.setThreshold(100);
|
||||
|
||||
// *************************************************************
|
||||
// * In this implementation we will always attempt to resolve
|
||||
// * the location of the server using the name server first, to
|
||||
// * determine if monitoring can be installed later...
|
||||
// *************************************************************
|
||||
cdevData input;
|
||||
cdevData output;
|
||||
cdevRequestObject & rnsReq =
|
||||
cdevRequestObject::attachRef("NameServer", "get");
|
||||
|
||||
// *****************************************************
|
||||
// * Insert domain and name in the input request object
|
||||
// * to be sent to the CDEV Name Server.
|
||||
// *****************************************************
|
||||
input.insert("name", server);
|
||||
input.insert("domain", domain);
|
||||
|
||||
// *****************************************************
|
||||
// * Query the Name Server to obtain the hostname and
|
||||
// * port of the specified domain and server.
|
||||
// *****************************************************
|
||||
if(rnsReq.send(input, output)==CDEV_SUCCESS)
|
||||
{
|
||||
output.get("host", serverHost, 255);
|
||||
output.get("port", &serverPort);
|
||||
output.get("status", &serverStatus);
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * Restore the error threshold to a reasonable level.
|
||||
// *************************************************************
|
||||
system_.setThreshold(CDEV_SEVERITY_ERROR);
|
||||
|
||||
// *************************************************************
|
||||
// * If the host and port have been specified, then use them
|
||||
// * rather than going through the CDEV Name Server.
|
||||
// *************************************************************
|
||||
if(host!=NULL && *host && port>0)
|
||||
{
|
||||
if(strcmp(serverHost, host) && serverPort==port)
|
||||
hostMatchesNS = 1;
|
||||
|
||||
strcpy(serverHost, host);
|
||||
serverPort = port;
|
||||
}
|
||||
else {
|
||||
if(*serverHost == 0 || serverPort<=0 || serverStatus!=0)
|
||||
{
|
||||
errCode = CDEV_ERROR;
|
||||
|
||||
// *********************************************
|
||||
// * If the hostname could not be found, report
|
||||
// * the error and set the return value to
|
||||
// * CDEV_ERROR.
|
||||
// *********************************************
|
||||
outputError(CDEV_SEVERITY_ERROR,
|
||||
"CLIPService::connect",
|
||||
"Cannot find host for server \"%s\" in domain \"%s\"",
|
||||
server, domain);
|
||||
}
|
||||
else hostMatchesNS = 1;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * If the hostname was discovered, then the errCode should be
|
||||
// * CDEV_SUCCESS. Attempt to connect to the server using the
|
||||
// * cdevReactor mechanisms.
|
||||
// *************************************************************
|
||||
if(errCode==CDEV_SUCCESS)
|
||||
{
|
||||
cdevInetAddr addr;
|
||||
|
||||
addr.set (serverPort, serverHost);
|
||||
|
||||
handler = new ServerHandler(server, this);
|
||||
|
||||
if(handler->open(addr)!=0)
|
||||
{
|
||||
outputError(CDEV_SEVERITY_ERROR,
|
||||
"CLIPService::connect",
|
||||
"Failed to connect to %s on port %i",
|
||||
serverHost,
|
||||
serverPort);
|
||||
delete handler;
|
||||
handler = NULL;
|
||||
}
|
||||
else {
|
||||
outputError(CDEV_SEVERITY_INFO,
|
||||
"CLIPService::connect",
|
||||
"Connected to %s on port %i",
|
||||
serverHost,
|
||||
serverPort);
|
||||
connections.insert(handler);
|
||||
|
||||
// *********************************************
|
||||
// * This calls the registerFd method of the
|
||||
// * service which will cause the FD Changed
|
||||
// * callbacks to be triggered.
|
||||
// *********************************************
|
||||
registerFd(handler->getHandle(), 1);
|
||||
|
||||
// *********************************************
|
||||
// * Install a Name Server monitor to maintain
|
||||
// * the status of the connection.
|
||||
// * Note: If a monitor has already been
|
||||
// * installed using this informations, then the
|
||||
// * CDEV Name Server service should not create
|
||||
// * a second monitor.
|
||||
// *
|
||||
// * Note: I am using the FifoQueue associated
|
||||
// * with the specific server in order to
|
||||
// * differentiate between the various servers.
|
||||
// *********************************************
|
||||
if(hostMatchesNS)
|
||||
{
|
||||
cdevData monData;
|
||||
cdevCallback monCb(nameServerCallback, (void *)getCallbackArg(server));
|
||||
cdevRequestObject & monReq = cdevRequestObject::attachRef("NameServer", "monitorOn");
|
||||
|
||||
monData.insert("name", server);
|
||||
monData.insert("domain", domain);
|
||||
monReq.sendCallback(monData, monCb);
|
||||
}
|
||||
|
||||
// *********************************************
|
||||
// * Here is where a "set ClientInfo" message
|
||||
// * will be sent to the server to provide
|
||||
// * descriptive information about the client.
|
||||
// *********************************************
|
||||
cdevData tagMap;
|
||||
int * tags;
|
||||
char ** ctags;
|
||||
int ntags;
|
||||
char * binary = NULL;
|
||||
size_t binaryLen = 0;
|
||||
|
||||
cdevData::readTagTable(tags, ctags, ntags);
|
||||
tagMap.insert(1, tags, ntags);
|
||||
tagMap.insert(2, ctags, ntags);
|
||||
|
||||
delete tags;
|
||||
delete ctags;
|
||||
handler->setTagChangeFlag(0);
|
||||
|
||||
cdevMessageBinary packet(handler->getClientID(),
|
||||
0, 0, 0, 0, CDEV_SERVER_OP, 0, 0,
|
||||
NULL, "set ClientInfo",
|
||||
&clientInfo.getClientData(),
|
||||
NULL, &tagMap);
|
||||
|
||||
packet.streamOut(&binary, &binaryLen);
|
||||
packet.detachData();
|
||||
|
||||
ServerInterface::enqueue(handler, binary, binaryLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <cdevClientService.h>
|
||||
|
||||
// *****************************************************************************
|
||||
// * newCLIPService :
|
||||
// * This function will be called by the cdevSystem object to create an
|
||||
// * initial instance of the CLIPService.
|
||||
// *****************************************************************************
|
||||
extern "C" cdevService * newCLIPService ( char * name, cdevSystem * system );
|
||||
|
||||
// *****************************************************************************
|
||||
// * class CLIPService :
|
||||
// * This class simply inherits from the cdevClientService and must define
|
||||
// * only a constructor and destructor.
|
||||
// *****************************************************************************
|
||||
class CLIPService : public cdevClientService
|
||||
{
|
||||
public:
|
||||
CLIPService ( char * name, cdevSystem & system = cdevSystem::defaultSystem());
|
||||
virtual ServerHandler * connect ( char * server, char * host = NULL, short port = 0 );
|
||||
virtual int getRequestObject ( char * device, char * message, cdevRequestObject * &req);
|
||||
|
||||
protected:
|
||||
virtual ~CLIPService ( void ) {};
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
service CLIP {
|
||||
tags {server, host, port}
|
||||
}
|
||||
|
||||
|
||||
class JAVAServer {
|
||||
verbs {get, set, monitorOn, monitorOff}
|
||||
attributes {
|
||||
Thing1 CLIP {server=JServer1, host=localhost, port=9900};
|
||||
Thing2 CLIP {server=JServer1, host=localhost, port=9900};
|
||||
}
|
||||
}
|
||||
|
||||
JAVAServer :
|
||||
JServer1
|
||||
;
|
||||
@@ -0,0 +1,30 @@
|
||||
ARCH = OS
|
||||
SHOBJ = YES
|
||||
|
||||
include $(CDEV)/extensions/cdevGenericServer/include/makeinclude/Makefile.$(ARCH)
|
||||
|
||||
APPNAME = "CDEV CLIP Client/Service"
|
||||
CXXINCLUDES = -I./
|
||||
|
||||
# ******************************************************************************
|
||||
# * The BINARIES definition names all of the binary files that should be deleted
|
||||
# * whenever "make clean" is executed.
|
||||
# ******************************************************************************
|
||||
BINARIES = $(BASELIB)/libCLIPService.a \
|
||||
$(BASELIB)/CLIPService.so
|
||||
|
||||
ifeq ($(SHOBJ), YES)
|
||||
LIBS = -L$(CDEVLIB) -lcdevGenericServer $(CDEVLIBS) $(OSLIBS)
|
||||
TARGETS = $(BASELIB)/CLIPService.so
|
||||
else
|
||||
LIBS = -L$(CDEVLIB) -lcdevGenericServer $(CDEVLIBS) $(OSLIBS)
|
||||
TARGETS = $(BASELIB)/libCLIPService.a
|
||||
endif
|
||||
|
||||
targets : $(TARGETS)
|
||||
|
||||
$(BASELIB)/CLIPService.so : $(OBJDIR)/CLIPService.o $(OBJDIR)/CLIPRequestObject.o
|
||||
$(LINK.so) -o $@ $^ -L$(CDEVLIB) -lcdevGenericServer $(NETLIBS)
|
||||
@mkdir -p $(CDEVSHOBJ)/$(CDEVVERSION)
|
||||
@cp $@ $(CDEVSHOBJ)/$(CDEVVERSION)/$(@F)
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
=> Building [Linux] in CDEV CLIP Client/Service
|
||||
=> g++ -c CLIPService.cc -o CLIPService.o
|
||||
target is .shobj/Linux/CLIPService.o and CLIPService.cc
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/fifo.h: In function `static class QueueBase::node * QueueBase::newNode()':
|
||||
In file included from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerHandler.h:17,
|
||||
from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerInterface.h:5,
|
||||
from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:7,
|
||||
from CLIPService.h:1,
|
||||
from CLIPService.cc:1:
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/fifo.h:76: warning: ANSI C++ forbids implicit conversion from `void *' in assignment
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/StringHash.h: In method `char * StringHashIterator::key()':
|
||||
In file included from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerInterface.h:7,
|
||||
from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:7,
|
||||
from CLIPService.h:1,
|
||||
from CLIPService.cc:1:
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/StringHash.h:227: warning: ANSI C++ forbids implicit conversion from `void *' in return
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerInterface.h: In method `class ServerHandler * ServerConnectionList::operator [](int)':
|
||||
In file included from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:7,
|
||||
from CLIPService.h:1,
|
||||
from CLIPService.cc:1:
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerInterface.h:30: warning: ANSI C++ forbids implicit conversion from `void *' in return
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevContextMap.h: In method `class cdevData * cdevContextMap::find(int)':
|
||||
In file included from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:9,
|
||||
from CLIPService.h:1,
|
||||
from CLIPService.cc:1:
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevContextMap.h:28: warning: ANSI C++ forbids implicit conversion from `void *' in return
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h: In method `class ServerHandler * CLIPService::connect(char *, char * = 0, short int = 0)':
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:99: method `class NSCallbackArg * cdevClientService::getCallbackArg(char *)' is private
|
||||
CLIPService.cc:205: within this context
|
||||
CLIPService.cc:205: in base initialization for class `cdevCallback'
|
||||
compile done\n
|
||||
=> g++ -c CLIPRequestObject.cc -o CLIPRequestObject.o
|
||||
target is .shobj/Linux/CLIPRequestObject.o and CLIPRequestObject.cc
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/fifo.h: In function `static class QueueBase::node * QueueBase::newNode()':
|
||||
In file included from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerHandler.h:17,
|
||||
from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerInterface.h:5,
|
||||
from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:7,
|
||||
from CLIPService.h:1,
|
||||
from CLIPRequestObject.cc:2:
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/fifo.h:76: warning: ANSI C++ forbids implicit conversion from `void *' in assignment
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/StringHash.h: In method `char * StringHashIterator::key()':
|
||||
In file included from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerInterface.h:7,
|
||||
from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:7,
|
||||
from CLIPService.h:1,
|
||||
from CLIPRequestObject.cc:2:
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/StringHash.h:227: warning: ANSI C++ forbids implicit conversion from `void *' in return
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerInterface.h: In method `class ServerHandler * ServerConnectionList::operator [](int)':
|
||||
In file included from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:7,
|
||||
from CLIPService.h:1,
|
||||
from CLIPRequestObject.cc:2:
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/ServerInterface.h:30: warning: ANSI C++ forbids implicit conversion from `void *' in return
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevContextMap.h: In method `class cdevData * cdevContextMap::find(int)':
|
||||
In file included from /home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevClientService.h:9,
|
||||
from CLIPService.h:1,
|
||||
from CLIPRequestObject.cc:2:
|
||||
/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/include/cdevContextMap.h:28: warning: ANSI C++ forbids implicit conversion from `void *' in return
|
||||
CLIPRequestObject.cc: In method `int CLIPRequestObject::getServerHandler(class ServerHandler **)':
|
||||
CLIPRequestObject.cc:30: member `server' is private
|
||||
CLIPRequestObject.cc:30: member `DDL_server' is private
|
||||
CLIPRequestObject.cc:30: member `server' is private
|
||||
CLIPRequestObject.cc:30: member `DDL_server' is private
|
||||
CLIPRequestObject.cc:31: member `server' is private
|
||||
CLIPRequestObject.cc:31: member `handler' is private
|
||||
CLIPRequestObject.cc:33: member `server' is private
|
||||
CLIPRequestObject.cc:38: member `handler' is private
|
||||
CLIPRequestObject.cc:39: member `handler' is private
|
||||
CLIPRequestObject.cc:42: member `handler' is private
|
||||
compile done\n
|
||||
start so build...
|
||||
=> Building shared object CLIPService.so
|
||||
/bin/sh: @@echo: command not found
|
||||
gcc: .shobj/Linux/CLIPService.o: No such file or directory
|
||||
gcc: .shobj/Linux/CLIPRequestObject.o: No such file or directory
|
||||
make: *** [/home/pss060/sls/watson/1.7/extensions/cdevGenericServer/lib/Linux/CLIPService.so] Error 1
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 948 B |
+948
@@ -0,0 +1,948 @@
|
||||
<! This document generated using mif2html Version 1.0 - Walt Akers - 1996 !>
|
||||
<head>
|
||||
<title>CDEV Script Service</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#E0E0FF">
|
||||
|
||||
<body>
|
||||
<! ************************ FILE : cdevScriptServiceTITLE.mif *****************************!>
|
||||
<br><hr><br>
|
||||
<table width=100%>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start ADDRESS-VERSION ***!><font size=+2 color=Black>
|
||||
CDEV Script Service
|
||||
</p>
|
||||
|
||||
</p>
|
||||
A Tool for Using Interactive Scripts from CDEV
|
||||
</p>
|
||||
|
||||
</p>
|
||||
Walt Akers
|
||||
</p>
|
||||
|
||||
</p>
|
||||
Version 1.0 February 11, 1997
|
||||
</p>
|
||||
|
||||
</p>
|
||||
TJNAF - Thomas Jefferson National Accelerator Facility
|
||||
</p>
|
||||
|
||||
<!*** Finish ADDRESS-VERSION ***!></p></font>
|
||||
</td></tr>
|
||||
</table>
|
||||
<! *************************** TABLE OF CONTENTS ****************************!>
|
||||
<br><hr><br>
|
||||
<table width=100%>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top align=center>
|
||||
<!*** Start CLASS-TOC-TITLE ***!><font size=+3><strong>
|
||||
Table of Contents
|
||||
<!*** Finish CLASS-TOC-TITLE ***!></p></strong></font>
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<table>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
1.
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF1">Script Service Fundamentals</a>
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF2">Overview of the Script Service</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF3">Features of the Script Service</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
2.
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF4">Building the Script Service</a>
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF5">Location of Files</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF6">Steps to Building Service</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
3.
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF7">Structure of Data Provided to the Script</a>
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF8">General Form of Data String</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF9">Representation of Scalar Data</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF10">Representation of Array Data</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
4.
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF11">Structure of Data Returned from the Script</a>
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF12">Returning Data to the Calling CDEV Application</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF13">General Form of String Data </a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF14">Returning a Single Result Packet </a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF15">Returning Multiple Result Packets </a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF16">Special Considerations</a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
5.
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF17">DDL Entries for the Script Service</a>
|
||||
<!*** Finish HEADING1TOC ***!><br></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start UHEADING2TOC ***!><font size=+1 color=Black>
|
||||
<a href="cdevScriptService.html#TOCREF18">Setting Up the DDL </a>
|
||||
<!*** Finish UHEADING2TOC ***!><br></font>
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
<! **************************** LIST OF FIGURES *****************************!>
|
||||
<br><hr><br>
|
||||
<table width=100%>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top align=center>
|
||||
<!*** Start CLASS-LOF-TITLE ***!><font size=+3><strong>
|
||||
List of Figures
|
||||
<!*** Finish CLASS-LOF-TITLE ***!></p></strong></font>
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
||||
Figure 7:
|
||||
<a href="cdevScriptService.html#LOFREF1">General form of string representation of cdevData</a>
|
||||
<!*** Finish FIGURELOF ***!><br></font>
|
||||
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
||||
Figure 8:
|
||||
<a href="cdevScriptService.html#LOFREF2">String representation of scalar data in a cdevData object</a>
|
||||
<!*** Finish FIGURELOF ***!><br></font>
|
||||
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
||||
Figure 9:
|
||||
<a href="cdevScriptService.html#LOFREF3">String representation of array data</a>
|
||||
<!*** Finish FIGURELOF ***!><br></font>
|
||||
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
||||
Figure 10:
|
||||
<a href="cdevScriptService.html#LOFREF4">Returning a single result packet to the CDEV application</a>
|
||||
<!*** Finish FIGURELOF ***!><br></font>
|
||||
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
||||
Figure 11:
|
||||
<a href="cdevScriptService.html#LOFREF5">Returning a multiple result packets to the CDEV application</a>
|
||||
<!*** Finish FIGURELOF ***!><br></font>
|
||||
<!*** Start FIGURELOF ***!><font size=+1 color=Black>
|
||||
Figure 12:
|
||||
<a href="cdevScriptService.html#LOFREF6">Simple DDL file for the Script Service</a>
|
||||
<!*** Finish FIGURELOF ***!><br></font>
|
||||
</td></tr>
|
||||
</table>
|
||||
<! ************************ FILE : ./cdevScriptService.mif *****************************!>
|
||||
<br><hr><br>
|
||||
<table width=100%>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
1.
|
||||
<!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
<a name="TOCREF1">
|
||||
Script Service Fundamentals
|
||||
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF2">
|
||||
Overview of the
|
||||
Script Service
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
The CDEV Script Service is designed to allow a a CDEV application to execute an
|
||||
external script to process a message. The output that is produced by the executable
|
||||
will be returned to the caller in the form of a cdevData. The CDEV Script Service
|
||||
meets the following requirements.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF3">
|
||||
Features of the
|
||||
Script Service
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<table>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
The filename of the script is associated with a CDEV device/message
|
||||
combination by using the "filename" field of the class-data in the CDEV DDL file.
|
||||
Syntax is described later in this document.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
A new process will be spawned for the script each time it is executed. Its standard
|
||||
output (stdout) file descriptor will be redirected to return data to the main CDEV
|
||||
application, allowing the script to return results to the parent process.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
The external executable file can be any form of user shell, batch file or binary
|
||||
application that is supported on the host platform.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
The Script Service supports all of CDEV's send mechanisms; "send",
|
||||
"sendNoBlock" and "sendCallback". Because of limits imposed on the number of
|
||||
active processes, the user is advised to use the synchronous "send" method
|
||||
whenever practical.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
When called by CDEV, the script will receive three arguments; the name of the
|
||||
CDEV device associated with the request, the message string that was submitted
|
||||
to the device, and a string that describes the contents of the outbound cdevData
|
||||
object.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
The reply that is written to the standard output by the script must have a specific
|
||||
format as described later in this document. A script may return more than one
|
||||
reply packet to the caller.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
The script notifies CDEV that it has written its last reply packet by writing "done"
|
||||
alone on a line to the standard output.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
If the script is to return multiple results, it should write "end" alone on a line to the
|
||||
standard output between each packet, and write "done" alone on a line following
|
||||
the last packet.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
If the script returns a value in the "status" tag of its reply packet, this will be
|
||||
provided to the caller as the completion code of the message. Traditionally a
|
||||
status of 0 indicates success, and all other values indicated an error occurred.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
<img src="bullet.jpg">
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BULLETED ***!><font size=+1 color=Black>
|
||||
Because the callback mechanism of the Script Service is triggered by output from
|
||||
the script, the script developer should at least write "done" to the standard output
|
||||
even if the application returns no output.
|
||||
<!*** Finish BULLETED ***!></p></font>
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
2.
|
||||
<!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
<a name="TOCREF4">
|
||||
Building the Script Service
|
||||
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF5">
|
||||
Location of Files
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
The source code for the Script Service is provided with the CDEV distribution starting
|
||||
with version 1.5. The source code is located in the directory $CDEV/extensions/
|
||||
ScriptService. The following steps should be taken to build the ScriptService.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF6">
|
||||
Steps to Building
|
||||
Service
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<table>
|
||||
<tr><td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
1.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
Obtain and install the CDEV distribution - Version 1.5 or higher.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
2.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
Follow the installation steps to build CDEV on your system. This includes setting
|
||||
all of the environment variables required by CDEV.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
3.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
Change directories to <em>$CDEV/extensions/ScriptService/src</em>.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
4.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
There is a collection of platform specific makefiles in the directory <em>$CDEV/
|
||||
extensions/cdevGenericServer/include/makeinclude</em>. Link the makefile that is
|
||||
appropriate to your architecture to the file Makefile.OS.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
<!*** Start INDENTED ***!><font size=+1 color=Black>
|
||||
For example, to link to the makefile for HP-UX, you would type the following
|
||||
command.
|
||||
</p>
|
||||
|
||||
</p>
|
||||
<em>ln -s Makefile.hpux Makefile.OS</em>
|
||||
</p>
|
||||
|
||||
<!*** Finish INDENTED ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
5.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start NUMBERED ***!><font size=+1 color=Black>
|
||||
Type make to compile and link the Script Service shared object. Note that you
|
||||
must be using GNU make in order to build this distribution.
|
||||
<!*** Finish NUMBERED ***!></p></font>
|
||||
</td></tr>
|
||||
</table>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
Upon completion the Makefile will generate the shared object for the Script Service
|
||||
and will install it into your CDEVSHOBJ directory. At this point you are ready to use
|
||||
the Script Service.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
3.
|
||||
<!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
<a name="TOCREF7">
|
||||
Structure of Data Provided to the Script
|
||||
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF8">
|
||||
General Form of
|
||||
Data String
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
When a developer makes a CDEV send call, he may provide outbound data in the
|
||||
form of a cdevData object. Before calling the script, this data is converted into a string
|
||||
and provided as the third argument to the application (the first argument is the device
|
||||
name and the second is the message). The structure of the outbound data string is of
|
||||
the following form.
|
||||
</p>
|
||||
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
||||
Figure 7:
|
||||
<a name="LOFREF1">
|
||||
General form of string representation of cdevData
|
||||
<table border=1><tr><td>
|
||||
<table>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black><strong><em>
|
||||
tag1="string value"
|
||||
tag2=1.00
|
||||
<!*** Finish PROGRAM ***!></strong></em></font></pre>
|
||||
</td></tr>
|
||||
</table>
|
||||
</tr></td></table>
|
||||
<AFrame 13>
|
||||
</a> <!*** Finish FIGURE ***!></p></em></font>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF9">
|
||||
Representation of
|
||||
Scalar Data
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
The above example shows two data entries of the form <em>tag=value</em>. Each entry is
|
||||
separated by a carriage return. The first entry has a tag name of <em>'tag1'</em> and a value of
|
||||
<em>'string value'</em>. You will note that <em>'string value'</em> is enclosed in double quotes in the
|
||||
example. This is used to notify the script that the value is a non-numeric character
|
||||
string. In the second data entry the value <em>'1.0' </em>is not enclosed in quotes, indicating that
|
||||
the value is a number.
|
||||
</p>
|
||||
The following example illustrates how scalar values stored in a cdevData object would
|
||||
look when they are passed to the script.
|
||||
</p>
|
||||
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
||||
Figure 8:
|
||||
<a name="LOFREF2">
|
||||
String representation of scalar data in a cdevData object
|
||||
<table border=1><tr><td>
|
||||
<table>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black><strong><em>
|
||||
Data stored in cdevData object:
|
||||
Tag: value
|
||||
Data Type: character string
|
||||
Value: Test
|
||||
|
||||
Tag: status
|
||||
Data Type: integer
|
||||
Value: 0
|
||||
|
||||
Tag: controlHigh
|
||||
Data Type: double
|
||||
Value: 1.001
|
||||
|
||||
String representation provided to script:
|
||||
value="Test"\\n
|
||||
status=0\\n
|
||||
controlHigh=1.001\\n
|
||||
<!*** Finish PROGRAM ***!></strong></em></font></pre>
|
||||
</td></tr>
|
||||
</table>
|
||||
</tr></td></table>
|
||||
<AFrame 1>
|
||||
</a> <!*** Finish FIGURE ***!></p></em></font>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF10">
|
||||
Representation of
|
||||
Array Data
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
If array data is stored in the outbound cdevData object, it too can be provided to the
|
||||
script. The data is structured in the standard C format where opening and closing
|
||||
braces mark the beginning and end (respectively) of each array bound. The following
|
||||
example illustrates how various arrays would be represented as strings.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
||||
Figure 9:
|
||||
<a name="LOFREF3">
|
||||
String representation of array data
|
||||
<table border=1><tr><td>
|
||||
<table>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black><strong><em>
|
||||
Data stored in cdevData object:
|
||||
Tag: value
|
||||
Data Type: character string [3]
|
||||
Value: "value1" "value2" "value3"
|
||||
|
||||
String representation provided to script:
|
||||
value={"value1","value2","value3"}\\n
|
||||
|
||||
<AFrame 5>
|
||||
|
||||
Data stored in cdevData object:
|
||||
Tag: value
|
||||
Data Type: double [3]
|
||||
Value: 1.0, 2.0, 3.01
|
||||
|
||||
String representation provided to script:
|
||||
value={1,2,3.01}\\n
|
||||
|
||||
<AFrame 6>
|
||||
|
||||
Data stored in cdevData object:
|
||||
Tag: value
|
||||
Data Type: double [3][2]
|
||||
Value: 1.0, 2.0, 3.0, 4.0, 5.0, 6.0
|
||||
|
||||
String representation provided to script:
|
||||
value={{1,2},{3,4},{5,6}}\\n
|
||||
<!*** Finish PROGRAM ***!></strong></em></font></pre>
|
||||
</td></tr>
|
||||
</table>
|
||||
</tr></td></table>
|
||||
<AFrame 3>
|
||||
</a> <!*** Finish FIGURE ***!></p></em></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
4.
|
||||
<!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
<a name="TOCREF11">
|
||||
Structure of Data Returned from the Script
|
||||
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF12">
|
||||
Returning Data to
|
||||
the Calling CDEV
|
||||
Application
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
Before CDEV starts the script, it creates a pipe that is used to pass data between the
|
||||
script and the CDEV application. One end of this pipe is maintained by the application
|
||||
and the other end of the pipe is provided to the script as its standard output. This
|
||||
means that anytime the script uses the "echo" command or the "printf" command, the
|
||||
data that it output's will be transmitted through the pipe to the parent application.
|
||||
</p>
|
||||
The script is responsible for formatting the data into a collection of character strings
|
||||
that can be recognized by the CDEV application.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF13">
|
||||
General Form of
|
||||
String Data
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
In general, the data that is returned from a script is of the same form as described in
|
||||
the preceding section, "<em>Structure of Data Provided to the Script</em>". The most notable
|
||||
difference is that the script must terminate the list by providing a character string that
|
||||
indicates that the group of data items is complete; the string "<em>end</em>" or "<em>done</em>" alone on
|
||||
a line.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF14">
|
||||
Returning a
|
||||
Single Result
|
||||
Packet
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
If the script is going to return exactly one result packet (<em>a group of tags and values that
|
||||
will be used to populate the result cdevData</em>), then it should write the string "<em>done</em>" on
|
||||
a line by itself immediately following the output data. This will notify the Script Service
|
||||
that no more data will be returned from the script.
|
||||
</p>
|
||||
The following example shows how a single result will be returned from a script. Note
|
||||
that the "status" tag contains the completion code that will be returned to the CDEV
|
||||
application.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
||||
Figure 10:
|
||||
<a name="LOFREF4">
|
||||
Returning a single result packet to the CDEV application
|
||||
<table border=1><tr><td>
|
||||
<table>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black><strong><em>
|
||||
#\\! /bin/csh -f
|
||||
|
||||
echo value=\\"Test\\"
|
||||
echo status=0
|
||||
echo controlLow=1.5
|
||||
echo controlHigh=25.1
|
||||
echo done
|
||||
<!*** Finish PROGRAM ***!></strong></em></font></pre>
|
||||
</td></tr>
|
||||
</table>
|
||||
</tr></td></table>
|
||||
<AFrame 7>
|
||||
</a> <!*** Finish FIGURE ***!></p></em></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF15">
|
||||
Returning
|
||||
Multiple Result
|
||||
Packets
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
Returning multiple results from a single script execution is not generally advised.
|
||||
However, If the script is going to return more than one result packet, then each interim
|
||||
packet should be terminated by the "<em>end</em>" keyword on a line by itself. The "<em>done</em>"
|
||||
keyword should follow the last entry.
|
||||
</p>
|
||||
The following example shows how two results will be returned from a script.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
||||
Figure 11:
|
||||
<a name="LOFREF5">
|
||||
Returning a multiple result packets to the CDEV application
|
||||
<table border=1><tr><td>
|
||||
<table>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black><strong><em>
|
||||
#\\! /bin/csh -f
|
||||
|
||||
echo value=\\"Start Result 1\\"
|
||||
echo status=0
|
||||
echo end
|
||||
echo value=\\"Start Result 2\\"
|
||||
echo status=-1
|
||||
echo done
|
||||
<!*** Finish PROGRAM ***!></strong></em></font></pre>
|
||||
</td></tr>
|
||||
</table>
|
||||
</tr></td></table>
|
||||
<AFrame 9>
|
||||
</a> <!*** Finish FIGURE ***!></p></em></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF16">
|
||||
Special
|
||||
Considerations
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
If the script that is being executed will not return a result, then the developer should
|
||||
still write "<em>done"</em> to the standard output in order to notify the CDEV application that it
|
||||
should no longer wait for output. If the script is not returning a result, it may write the
|
||||
terminating <em>"done"</em> at the beginning of the script or at the end. Because synchronous
|
||||
calls will block until a reply is received, the developer should return a result to the
|
||||
CDEV application as quickly as possible.
|
||||
</p>
|
||||
If the developer never writes anything to the standard output, then the user specified
|
||||
CDEV callback will never be executed... therefore, it is crucial to notify the CDEV
|
||||
application when the script has completed.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top align=right>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
5.
|
||||
<!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start HEADING1 ***!><font size=+3 color=Black><strong>
|
||||
<a name="TOCREF17">
|
||||
DDL Entries for the Script Service
|
||||
</a> <!*** Finish HEADING1 ***!></p></strong></font>
|
||||
</td></tr>
|
||||
<tr><td valign=top>
|
||||
<!*** Start UHEADING2 ***!><font size=+1 color=Black><strong>
|
||||
<a name="TOCREF18">
|
||||
Setting Up the
|
||||
DDL
|
||||
</a> <!*** Finish UHEADING2 ***!></p></strong></font>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
The following example illustrates how to add a service entry to identify the Script
|
||||
Service and how to use the class-data to specify the filename that the Script Service
|
||||
will execute to service a message.
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
<!*** Start FIGURE ***!><font size=+0 color=Black><em>
|
||||
Figure 12:
|
||||
<a name="LOFREF6">
|
||||
Simple DDL file for the Script Service
|
||||
<table border=1><tr><td>
|
||||
<table>
|
||||
<tr><td>
|
||||
<! ***** Empty Column ***** !>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<!*** Start PROGRAM ***!><pre><font size=+0 color=Black><strong><em>
|
||||
/*
|
||||
* This is the service definition, it tells CDEV that there is
|
||||
* a service named Script and that it will use the cdevData
|
||||
* tag 'filename' to read configuration information from the
|
||||
* DDL file entries.
|
||||
*/
|
||||
service Script
|
||||
{
|
||||
tags {filename}
|
||||
}
|
||||
|
||||
/*
|
||||
* This class definition identifies the class scriptClass which
|
||||
* supports the "get and "set" commands on attributes "attrib0"
|
||||
* and "attrib1". Note that attrib0 will call script /bin/ouch
|
||||
* and attrib1 will call script /bin/wammo.
|
||||
*/
|
||||
class scriptClass
|
||||
{
|
||||
verbs {get, set}
|
||||
attributes
|
||||
{
|
||||
attrib0 Script {filename = /bin/ouch};
|
||||
attrib1 Script {filename = /bin/wammo};
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, the CDEV DDL identifies two devices that are of type
|
||||
* scriptClass. Any time one of the supported messages is passed
|
||||
* to one of these devices it will activate the corresponding
|
||||
* script.
|
||||
*/
|
||||
scriptClass : device0, device1;
|
||||
|
||||
<!*** Finish PROGRAM ***!></strong></em></font></pre>
|
||||
</td></tr>
|
||||
</table>
|
||||
</tr></td></table>
|
||||
<AFrame 11>
|
||||
</a> <!*** Finish FIGURE ***!></p></em></font>
|
||||
<!*** Start BODY ***!><font size=+1 color=Black>
|
||||
|
||||
<!*** Finish BODY ***!></p></font>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#! /bin/csh
|
||||
|
||||
if( -f fmbatch.dat) rm fmbatch.dat
|
||||
if( -d html) rm -rf html
|
||||
mkdir -p html
|
||||
cp $CDEV/doc/bullet.jpg html
|
||||
|
||||
foreach x (`find . -name \*.doc -a ! -name \*TOC.doc -a ! -name \*LOF.doc`)
|
||||
echo "Open $x" >> fmbatch.dat
|
||||
echo "SaveAs ma $x html/`basename $x .doc`.mif" >> fmbatch.dat
|
||||
end
|
||||
|
||||
fmbatch fmbatch.dat
|
||||
|
||||
cd html
|
||||
|
||||
foreach x (`find . -name \*.mif -a ! -name \*TITLE.mif`)
|
||||
mif2html -t 'CDEV Script Service' -o `basename $x .mif`.html `basename $x .mif`TITLE.mif \-TOC \-LOF $x
|
||||
end
|
||||
|
||||
rm *.mif
|
||||
Binary file not shown.
Binary file not shown.
Executable
+46
@@ -0,0 +1,46 @@
|
||||
ARCH = OS
|
||||
SHOBJ = YES
|
||||
|
||||
include $(CDEV)/extensions/cdevGenericServer/include/makeinclude/Makefile.$(ARCH)
|
||||
|
||||
APPNAME = "CDEV/ACE Script Service"
|
||||
CXXINCLUDES = -I./
|
||||
BASEBIN = ./
|
||||
SO_LIBS = $(OSLIBS)
|
||||
SO_SRCS = ScriptService.cc \
|
||||
ScriptRequestObject.cc \
|
||||
ScriptList.cc
|
||||
OBJS = $(OBJDIR)/ScriptService.o \
|
||||
$(OBJDIR)/ScriptRequestObject.o \
|
||||
$(OBJDIR)/ScriptList.o
|
||||
|
||||
# ******************************************************************************
|
||||
# * The BINARIES definition names all of the binary files that should be deleted
|
||||
# * whenever "make clean" is executed.
|
||||
# ******************************************************************************
|
||||
BINARIES = $(CDEVLIB)/libScriptService.a \
|
||||
$(CDEVSHOBJ)/$(CDEVVERSION)/ScriptService.so
|
||||
|
||||
ifeq ($(SHOBJ), YES)
|
||||
LIBS = $(CDEVLIBS) $(OSLIBS)
|
||||
TARGETS = $(CDEVSHOBJ)/$(CDEVVERSION)/ScriptService.so
|
||||
else
|
||||
LIBS = $(CDEVLIBS) -lScriptService $(OSLIBS)
|
||||
TARGETS = $(CDEVLIB)/libScriptService.a
|
||||
endif
|
||||
|
||||
targets : $(TARGETS)
|
||||
|
||||
$(CDEVSHOBJ)/$(CDEVVERSION)/ScriptService.so : $(OBJS)
|
||||
@rm -f $@
|
||||
@$(SOBUILD)
|
||||
@mkdir -p $(CDEVSHOBJ)/$(CDEVVERSION)
|
||||
@echo "<= Done...\n"
|
||||
|
||||
$(CDEVLIB)/libScriptService.a : $(OBJS)
|
||||
@rm -f $@
|
||||
@echo "=> Building archive library $(@F)"
|
||||
@echo " => Linking $(@F) from objects"
|
||||
@$(LINK.a) $@ $^
|
||||
@$(RANLIB) $@ > /dev/null
|
||||
@echo "<= Done...\n"
|
||||
Executable
+958
@@ -0,0 +1,958 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with the construction of a script service.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
// Revision History:
|
||||
// ScriptList.cc,v
|
||||
// Revision 1.3 1997/02/14 20:43:40 akers
|
||||
// Ongoing improvement
|
||||
//
|
||||
// Revision 1.2 1997/02/14 20:06:32 akers
|
||||
// Ongoing improvement
|
||||
//
|
||||
// Revision 1.1 1997/02/11 17:37:22 akers
|
||||
// Directory restructure
|
||||
//
|
||||
// Revision 1.7 1997/02/10 20:31:23 akers
|
||||
// Ongoing improvement
|
||||
//
|
||||
// Revision 1.6 1997/02/07 16:19:43 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.5 1997/02/06 20:27:48 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.4 1997/01/31 21:09:58 akers
|
||||
// Ongoing Development
|
||||
//
|
||||
// Revision 1.3 1997/01/31 18:51:26 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.2 1997/01/31 16:21:22 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.1 1997/01/30 20:35:33 akers
|
||||
// Initial installation of Script Service
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
#include <ScriptList.h>
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptData::ScriptData :
|
||||
// * Constructor for the class...
|
||||
// *****************************************************************************
|
||||
ScriptData::ScriptData ( cdevTranObj & Xobj )
|
||||
: next(NULL), data(new cdevData),
|
||||
xobj(&Xobj), inputBuf(NULL),
|
||||
inputBufLen(0), amntRead(0),
|
||||
process(0), finished(0), callbackCount(0)
|
||||
{
|
||||
// *********************************************************************
|
||||
// * Attempt to create the pipe that will be used to return
|
||||
// * the result to the class.
|
||||
// *********************************************************************
|
||||
if(pipe((int *)&sp)!=0)
|
||||
{
|
||||
sp.readFD = -1;
|
||||
sp.writeFD = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptData::data2Buffer :
|
||||
// * This method is used to convert a cdevData object into a
|
||||
// * series of strings that can be used by the script.
|
||||
// *****************************************************************************
|
||||
int ScriptData::data2Buffer ( cdevData & data, char *& buf, int &bufLen)
|
||||
{
|
||||
cdevDataIterator iter(&data);
|
||||
int i;
|
||||
int idx = 0;
|
||||
struct DataPack
|
||||
{
|
||||
char * tag;
|
||||
char ** ptr;
|
||||
double * dPtr;
|
||||
size_t ptrCnt;
|
||||
int quoted;
|
||||
cdevBounds * bounds;
|
||||
size_t boundsCnt;
|
||||
} dataPack[256];
|
||||
|
||||
memset(dataPack, 0, sizeof(dataPack));
|
||||
|
||||
// *********************************************************************
|
||||
// * Iterate through the cdevData object and collect the data
|
||||
// * that is stored into an array of character strings.
|
||||
// *********************************************************************
|
||||
for(bufLen=0, iter.init(); !iter && idx<256; idx++)
|
||||
{
|
||||
// *************************************************************
|
||||
// * Get the tag string and add the length of that plus
|
||||
// * the length of a seperating equals sign (=) to the
|
||||
// * buffer length.
|
||||
// *************************************************************
|
||||
data.tagI2C(iter.tag(), dataPack[idx].tag);
|
||||
bufLen+=strlen(dataPack[idx].tag)+2;
|
||||
|
||||
// *************************************************************
|
||||
// * Get the number of elements in the array.
|
||||
// *************************************************************
|
||||
data.getElems(dataPack[idx].tag, &dataPack[idx].ptrCnt);
|
||||
|
||||
// *************************************************************
|
||||
// * If the data object is a string, add two times the
|
||||
// * number of elements to the buffer length (to account
|
||||
// * for double quotes around each entry.)
|
||||
// *************************************************************
|
||||
if(data.getType(dataPack[idx].tag)==CDEV_STRING ||
|
||||
data.getType(dataPack[idx].tag)==CDEV_TIMESTAMP)
|
||||
{
|
||||
dataPack[idx].quoted = 1;
|
||||
bufLen+=(2*dataPack[idx].ptrCnt);
|
||||
|
||||
// *****************************************************
|
||||
// * Allocate an array of character strings to
|
||||
// * be used to extract the array as a
|
||||
// * collection of strings and increase the
|
||||
// * buffer length to accomodate all of the
|
||||
// * items.
|
||||
// *****************************************************
|
||||
dataPack[idx].ptr = new char * [dataPack[idx].ptrCnt];
|
||||
data.get(dataPack[idx].tag, dataPack[idx].ptr);
|
||||
for(i=0; i<dataPack[idx].ptrCnt; i++)
|
||||
{
|
||||
bufLen+=strlen(dataPack[idx].ptr[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// *****************************************************
|
||||
// * Allocate an array of doubles to
|
||||
// * be used to extract the array as a
|
||||
// * collection and increase the buffer length
|
||||
// * to accomodate all of the items.
|
||||
// *****************************************************
|
||||
dataPack[idx].dPtr = new double [dataPack[idx].ptrCnt];
|
||||
data.get(dataPack[idx].tag, dataPack[idx].dPtr);
|
||||
bufLen += 21*dataPack[idx].ptrCnt;
|
||||
}
|
||||
// *************************************************************
|
||||
// * Add 1 character for each entry to account for
|
||||
// * commas between entries.
|
||||
// *************************************************************
|
||||
bufLen += dataPack[idx].ptrCnt;
|
||||
|
||||
// *************************************************************
|
||||
// * Get the number of dimensions in the tagged data
|
||||
// * item.
|
||||
// *************************************************************
|
||||
data.getDim(dataPack[idx].tag, &dataPack[idx].boundsCnt);
|
||||
|
||||
// *************************************************************
|
||||
// * If the data is an array or vector, then calculate
|
||||
// * the amount of space that will have to be used
|
||||
// * to store the separating brace characters (and commas).
|
||||
// *************************************************************
|
||||
if(dataPack[idx].boundsCnt!=0)
|
||||
{
|
||||
int braceCount = 1;
|
||||
|
||||
dataPack[idx].bounds = new cdevBounds[dataPack[idx].boundsCnt];
|
||||
data.getBounds(dataPack[idx].tag, dataPack[idx].bounds, dataPack[idx].boundsCnt);
|
||||
|
||||
for(i=0; i<dataPack[idx].boundsCnt-1; i++)
|
||||
{
|
||||
if(i==0) braceCount +=
|
||||
dataPack[idx].bounds[i].length;
|
||||
else braceCount +=
|
||||
dataPack[idx].bounds[i-1].length*
|
||||
dataPack[idx].bounds[i].length;
|
||||
}
|
||||
bufLen += braceCount*3;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * Add space for the separating carriage return.
|
||||
// *************************************************************
|
||||
bufLen+=1;
|
||||
|
||||
// *************************************************************
|
||||
// * Move to the next item in the list.
|
||||
// *************************************************************
|
||||
++iter;
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * Allocate a buffer of sufficient size to hold the result
|
||||
// * plus a NULL terminating character and an opening and closing
|
||||
// * single quote.
|
||||
// *********************************************************************
|
||||
if(idx) {
|
||||
buf = new char [bufLen+1+2];
|
||||
*buf = 0;
|
||||
}
|
||||
else {
|
||||
buf = NULL;
|
||||
bufLen = 0;
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * Walk through each item in the list and place it in the
|
||||
// * data buffer.
|
||||
// *********************************************************************
|
||||
int max = idx;
|
||||
for(idx=0; idx<max; idx++)
|
||||
{
|
||||
char * ptr = buf+strlen(buf);
|
||||
sprintf(ptr, "%s=", dataPack[idx].tag);
|
||||
|
||||
if(!dataPack[idx].boundsCnt)
|
||||
{
|
||||
if(dataPack[idx].quoted)
|
||||
sprintf(ptr+strlen(ptr), "\"%s\"\n", dataPack[idx].ptr[0]);
|
||||
else sprintf(ptr+strlen(ptr), "%g\n", dataPack[idx].dPtr[0]);
|
||||
}
|
||||
else {
|
||||
size_t ptrIdx = 0;
|
||||
strcat(ptr, "{");
|
||||
if(dataPack[idx].quoted)
|
||||
{
|
||||
dataArray2Buffer(ptr+strlen(ptr),
|
||||
dataPack[idx].ptr,
|
||||
ptrIdx,
|
||||
dataPack[idx].bounds,
|
||||
dataPack[idx].boundsCnt,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataArray2Buffer(ptr+strlen(ptr),
|
||||
dataPack[idx].dPtr,
|
||||
ptrIdx,
|
||||
dataPack[idx].bounds,
|
||||
dataPack[idx].boundsCnt,
|
||||
0);
|
||||
}
|
||||
strcat(ptr, "}\n");
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * Delete the allocated contents of the dataPack once
|
||||
// * it is no longer needed.
|
||||
// *************************************************************
|
||||
if(dataPack[idx].quoted)
|
||||
{
|
||||
for(int j=0; j<dataPack[idx].ptrCnt; j++)
|
||||
{
|
||||
delete dataPack[idx].ptr[j];
|
||||
}
|
||||
delete dataPack[idx].ptr;
|
||||
}
|
||||
else delete dataPack[idx].dPtr;
|
||||
delete dataPack[idx].bounds;
|
||||
}
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::dataArray2Buffer :
|
||||
// * This is a method that is called recursively to dump the contents
|
||||
// * of a string array to the buffer.
|
||||
// *****************************************************************************
|
||||
void ScriptData::dataArray2Buffer (char * output,
|
||||
char ** ptr,
|
||||
size_t & ptrIdx,
|
||||
cdevBounds * bounds,
|
||||
size_t nBounds,
|
||||
size_t boundsIdx)
|
||||
{
|
||||
for(int i=0; i<bounds[boundsIdx].length; i++)
|
||||
{
|
||||
if(boundsIdx<nBounds-1)
|
||||
{
|
||||
strcat(output, "{");
|
||||
dataArray2Buffer(output+strlen(output), ptr, ptrIdx, bounds, nBounds, boundsIdx+1);
|
||||
if(i+1<bounds[boundsIdx].length) strcat(output, "},");
|
||||
else strcat(output, "}");
|
||||
}
|
||||
else {
|
||||
output+=strlen(output);
|
||||
if(i+1<bounds[boundsIdx].length) sprintf(output, "\"%s\",", ptr[ptrIdx++]);
|
||||
else sprintf(output, "\"%s\"", ptr[ptrIdx++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::dataArray2Buffer :
|
||||
// * This is a method that is called recursively to dump the contents
|
||||
// * of a double array to the buffer.
|
||||
// *****************************************************************************
|
||||
void ScriptData::dataArray2Buffer (char * output,
|
||||
double * ptr,
|
||||
size_t & ptrIdx,
|
||||
cdevBounds * bounds,
|
||||
size_t nBounds,
|
||||
size_t boundsIdx)
|
||||
{
|
||||
for(int i=0; i<bounds[boundsIdx].length; i++)
|
||||
{
|
||||
if(boundsIdx<nBounds-1)
|
||||
{
|
||||
strcat(output, "{");
|
||||
dataArray2Buffer(output+strlen(output), ptr, ptrIdx, bounds, nBounds, boundsIdx+1);
|
||||
if(i+1<bounds[boundsIdx].length) strcat(output, "},");
|
||||
else strcat(output, "}");
|
||||
}
|
||||
else {
|
||||
output+=strlen(output);
|
||||
if(i+1<bounds[boundsIdx].length) sprintf(output, "%g,", ptr[ptrIdx++]);
|
||||
else sprintf(output, "%g", ptr[ptrIdx++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptData::buffer2Data :
|
||||
// * This method allows the ScriptData class to read the inbound
|
||||
// * results of the script inot a cdevData buffer.
|
||||
// *
|
||||
// * Each line of the result should be structured as such.
|
||||
// *
|
||||
// * Tag value\n
|
||||
// *
|
||||
// * All results are assumed to be doubles unless they are enclosed
|
||||
// * in double quotes (").
|
||||
// *
|
||||
// * If an array of items is returned, it should be enclosed in
|
||||
// * braces as described below.
|
||||
// *
|
||||
// * 1) Returning a string:
|
||||
// *
|
||||
// * value="Test"\n
|
||||
// * status "Running very well"\n
|
||||
// *
|
||||
// * 2) Returning a double:
|
||||
// * value=10.01\n
|
||||
// * status=1\n
|
||||
// *
|
||||
// * 3) Returning an array of strings
|
||||
// * value={"John","Jacob","Jingleheimer","Schmidt"}\n
|
||||
// *
|
||||
// * 4) Returning a two dimensional array of doubles: ie x[2][3]
|
||||
// * value={{1.0,2.0,3.0}{4.0,5.0,6.0}}\n
|
||||
// *
|
||||
// *****************************************************************************
|
||||
int ScriptData::buffer2Data ( char * &buf, cdevData & data )
|
||||
{
|
||||
int done = 0;
|
||||
char * ptr = buf;
|
||||
|
||||
while(ptr && *ptr)
|
||||
{
|
||||
while(isspace(*ptr)) ptr++;
|
||||
char * tag = ptr;
|
||||
|
||||
// *************************************************************
|
||||
// * Find the end of the tag and remove any trailing
|
||||
// * spaces that are associated with it.
|
||||
// *************************************************************
|
||||
if(*tag) ptr = strchr(ptr, '=');
|
||||
|
||||
// *************************************************************
|
||||
// * If the pointer does not point to a valid line, jump to
|
||||
// * the next line and continue from the top of the loop.
|
||||
// *************************************************************
|
||||
if(!ptr || !(*ptr))
|
||||
{
|
||||
ptr = strchr(ptr, '\n');
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
char *temp = ptr-1;
|
||||
*(ptr++) = 0;
|
||||
while(isspace(*temp)) *(temp--)=0;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * Find the beginning of the data.
|
||||
// *************************************************************
|
||||
while(*ptr && isspace(*ptr)) ptr++;
|
||||
|
||||
// *************************************************************
|
||||
// * Beginning of an array of things.
|
||||
// *************************************************************
|
||||
if(*ptr=='{')
|
||||
{
|
||||
cdevDataTypes dataType = CDEV_DOUBLE;
|
||||
char ** strData = NULL;
|
||||
double * dblData = NULL;
|
||||
char * tPtr = ptr;
|
||||
cdevBounds * bounds;
|
||||
int nDim = 0;
|
||||
int dimIdx = 0;
|
||||
int itmCnt = 0;
|
||||
int itmIdx = 0;
|
||||
int chkSum = 1;
|
||||
|
||||
// *****************************************************
|
||||
// * Count the number of opening braces, this will
|
||||
// * indicate the number of dimensions in the array.
|
||||
// *****************************************************
|
||||
while(*(tPtr++)=='{') nDim++;
|
||||
bounds = new cdevBounds[nDim];
|
||||
for(dimIdx=0; dimIdx<nDim; dimIdx++)
|
||||
{
|
||||
bounds[dimIdx].offset = 0;
|
||||
bounds[dimIdx].length = 0;
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// * Now count the number of the dimensions in the array
|
||||
// *****************************************************
|
||||
for(tPtr=ptr+1, dimIdx=0; dimIdx>=0 && *tPtr; tPtr++)
|
||||
{
|
||||
if(*tPtr=='"')
|
||||
{
|
||||
tPtr = strchr(tPtr+1, '"');
|
||||
dataType = CDEV_STRING;
|
||||
}
|
||||
else if(*tPtr=='}')
|
||||
{
|
||||
if(dimIdx==nDim-1) bounds[dimIdx].length++;
|
||||
dimIdx--;
|
||||
}
|
||||
else if(*tPtr=='{')
|
||||
{
|
||||
bounds[dimIdx++].length++;
|
||||
}
|
||||
else if(*tPtr==',' && dimIdx==nDim-1)
|
||||
{
|
||||
bounds[dimIdx].length++;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// * At this point, the last element of the bounds
|
||||
// * array will contain the total count of items.
|
||||
// *****************************************************
|
||||
itmCnt = bounds[nDim-1].length;
|
||||
|
||||
// *****************************************************
|
||||
// * To set each bounds element to its actual array
|
||||
// * dimension, it will be necessary to divide it by
|
||||
// * the size of its predecessor - working backwards.
|
||||
// *****************************************************
|
||||
for(dimIdx = nDim-2; dimIdx>=0; dimIdx--)
|
||||
{
|
||||
bounds[dimIdx+1].length /= bounds[dimIdx].length;
|
||||
}
|
||||
for(dimIdx = 0; dimIdx<nDim; dimIdx++)
|
||||
{
|
||||
chkSum*=bounds[dimIdx].length;
|
||||
}
|
||||
|
||||
if(chkSum==itmCnt && chkSum>0)
|
||||
{
|
||||
// *****************************************************
|
||||
// * Allocate a buffer of the correct type to hold the
|
||||
// * data.
|
||||
// *****************************************************
|
||||
if(dataType == CDEV_STRING) strData = new char *[itmCnt];
|
||||
else dblData = new double [itmCnt];
|
||||
|
||||
// *****************************************************
|
||||
// * Walk through the data and accumulate the items
|
||||
// * into the array.
|
||||
// *****************************************************
|
||||
tPtr = ptr;
|
||||
dimIdx = -1;
|
||||
|
||||
do {
|
||||
if(*tPtr=='{')
|
||||
{
|
||||
int jumpTheComma = 0;
|
||||
|
||||
dimIdx++;
|
||||
tPtr++;
|
||||
|
||||
if(*tPtr && dimIdx==nDim-1) do
|
||||
{
|
||||
if(*tPtr==',' && jumpTheComma) tPtr++;
|
||||
|
||||
while(isspace(*tPtr)) tPtr++;
|
||||
if(dataType==CDEV_DOUBLE)
|
||||
{
|
||||
dblData[itmIdx++] = atof(tPtr);
|
||||
while(*tPtr && *tPtr!=',' && *tPtr!='}') tPtr++;
|
||||
}
|
||||
else {
|
||||
char oldEndVal;
|
||||
char * ePtr;
|
||||
if(*tPtr=='"')
|
||||
{
|
||||
tPtr++;
|
||||
ePtr = strchr(tPtr, '"');
|
||||
}
|
||||
else for(ePtr=tPtr; *ePtr && *ePtr!=',' && *ePtr!='}'; ePtr++);
|
||||
|
||||
if(ePtr)
|
||||
{
|
||||
oldEndVal = *ePtr;
|
||||
*ePtr = 0;
|
||||
}
|
||||
|
||||
strData[itmIdx++] = strdup(tPtr);
|
||||
|
||||
if(ePtr)
|
||||
{
|
||||
*ePtr = oldEndVal;
|
||||
tPtr = (*ePtr=='"')?ePtr+1:ePtr;
|
||||
}
|
||||
else tPtr = tPtr+strlen(tPtr);
|
||||
}
|
||||
jumpTheComma = (*tPtr==',')?1:0;
|
||||
} while(*tPtr!='}' && *tPtr);
|
||||
}
|
||||
else if(*tPtr=='}')
|
||||
{
|
||||
dimIdx--;
|
||||
tPtr++;
|
||||
}
|
||||
else tPtr++;
|
||||
} while (*tPtr && itmIdx<itmCnt && dimIdx>=0);
|
||||
|
||||
if(dataType==CDEV_STRING)
|
||||
{
|
||||
data.insert(tag, strData, itmCnt, nDim);
|
||||
for(int x=0; x<itmCnt; x++) delete strData[x];
|
||||
delete strData;
|
||||
}
|
||||
else {
|
||||
data.insert(tag, dblData, itmCnt, nDim);
|
||||
delete dblData;
|
||||
}
|
||||
|
||||
data.setBounds(tag, bounds, nDim);
|
||||
}
|
||||
|
||||
delete bounds;
|
||||
for(ptr=tPtr; *ptr && *ptr!='\n'; ptr++);
|
||||
}
|
||||
// *************************************************************
|
||||
// * Beginning of a string.
|
||||
// *************************************************************
|
||||
else if(*ptr=='"')
|
||||
{
|
||||
ptr++;
|
||||
char * temp = ptr;
|
||||
while(*temp!='"') temp++;
|
||||
if(*temp=='"')
|
||||
{
|
||||
*(temp++)=0;
|
||||
data.insert(tag, ptr);
|
||||
}
|
||||
for(ptr = temp; *ptr && *ptr!='\n'; ptr++);
|
||||
}
|
||||
// *************************************************************
|
||||
// * Beginning of a double.
|
||||
// *************************************************************
|
||||
else if(*ptr)
|
||||
{
|
||||
data.insert(tag, atof(ptr));
|
||||
while(*ptr && *ptr!='\n') ptr++;
|
||||
}
|
||||
}
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptData::fireCallback :
|
||||
// * Deploys the callback associated with the class instance.
|
||||
// *****************************************************************************
|
||||
void ScriptData::fireCallback ( int result, void * arg, cdevRequestObject &req, cdevData & data, int partial)
|
||||
{
|
||||
// *********************************************************************
|
||||
// * Fire the user provided callback and increment the counter.
|
||||
// *********************************************************************
|
||||
xobj->userCallback_->fireCallback ( result, arg, req, data, partial );
|
||||
callbackCount++;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptData::dispatch :
|
||||
// * This method is responsible for collecting data from the
|
||||
// * read file descriptor, and executing the callback associated
|
||||
// * with it.
|
||||
// *
|
||||
// * This method will return the number of messages that it handled.
|
||||
// *****************************************************************************
|
||||
int ScriptData::dispatch ( void )
|
||||
{
|
||||
int nHandled = 0;
|
||||
if(!finished)
|
||||
{
|
||||
int count = 0;
|
||||
int stat_val;
|
||||
// *************************************************************
|
||||
// * Find out how many bytes are ready to read.
|
||||
// *************************************************************
|
||||
while(ioctl(sp.readFD, FIONREAD, &count)==0 && count>0)
|
||||
{
|
||||
// *****************************************************
|
||||
// * If the input buffer has not already been
|
||||
// * allocated, then allocate a new one that
|
||||
// * is of sufficient size in increments of
|
||||
// * 1024 bytes.
|
||||
// *****************************************************
|
||||
if(inputBufLen==0)
|
||||
{
|
||||
inputBufLen = (count/1024+1)*1024;
|
||||
inputBuf = (char *)malloc(inputBufLen);
|
||||
}
|
||||
// *****************************************************
|
||||
// * If the existing buffer is not sufficiently
|
||||
// * large, then allocate a new one that is
|
||||
// * of sufficient size in increments of
|
||||
// * 1024 bytes.
|
||||
// *********************************************
|
||||
else if(amntRead + count > inputBufLen)
|
||||
{
|
||||
inputBufLen = ((amntRead+count)/1024+1)*1024;
|
||||
inputBuf = (char *)realloc(inputBuf, inputBufLen);
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// * Read the data that is ready into the buffer
|
||||
// *****************************************************
|
||||
amntRead += read(sp.readFD, inputBuf+amntRead, count);
|
||||
|
||||
// *****************************************************
|
||||
// * NULL terminate the buffer to prevent memory
|
||||
// * overruns while performing string operations
|
||||
// *****************************************************
|
||||
inputBuf[amntRead] = 0;
|
||||
|
||||
int done = 0;
|
||||
|
||||
// *****************************************************
|
||||
// * Search the data for the "done" or "end" keywords
|
||||
// * on a line by themselves... Either of these
|
||||
// * keywords indicate the end of a data transmission.
|
||||
// *****************************************************
|
||||
do {
|
||||
char * ePtr = NULL;
|
||||
|
||||
if (strncmp(inputBuf, "end\n", 4)==0 ||
|
||||
strncmp(inputBuf, "done\n", 5)==0)
|
||||
{
|
||||
ePtr = inputBuf;
|
||||
}
|
||||
else if((ePtr = strstr(inputBuf, "\nend\n"))!=NULL ||
|
||||
(ePtr = strstr(inputBuf, "\ndone\n"))!=NULL)
|
||||
{
|
||||
ePtr++;
|
||||
}
|
||||
else done = 1;
|
||||
|
||||
if(ePtr && *ePtr)
|
||||
{
|
||||
if(*ePtr=='d')
|
||||
{
|
||||
*ePtr = 0;
|
||||
ePtr += 5;
|
||||
finished = 1;
|
||||
}
|
||||
else {
|
||||
*ePtr = 0;
|
||||
ePtr += 4;
|
||||
}
|
||||
|
||||
buffer2Data (inputBuf, *data);
|
||||
strcpy(inputBuf, ePtr);
|
||||
amntRead = strlen(inputBuf);
|
||||
|
||||
// *************************************
|
||||
// * If no more data is ready,
|
||||
// * determine if the process
|
||||
// * is still alive.
|
||||
// *************************************
|
||||
stat_val = 0;
|
||||
if(waitpid(process, &stat_val, WNOHANG)==process &&
|
||||
(errno==ECHILD || WIFEXITED(stat_val)))
|
||||
{
|
||||
finished = 1;
|
||||
}
|
||||
|
||||
// *************************************
|
||||
// * Transfer the data from the
|
||||
// * temporary data object into
|
||||
// * the user-defined result
|
||||
// * data object.
|
||||
// *************************************
|
||||
if(xobj->resultData_==NULL)
|
||||
xobj->resultData_ = data;
|
||||
else *(xobj->resultData_) = *data;
|
||||
|
||||
// *************************************
|
||||
// * Fire the user provided
|
||||
// * callback and increment the
|
||||
// * callback counter. The status as
|
||||
// * returned in the cdevData object
|
||||
// * is the status for the request.
|
||||
// *************************************
|
||||
int status = CDEV_SUCCESS;
|
||||
xobj->resultData_->get("status", &status);
|
||||
fireCallback
|
||||
(
|
||||
status,
|
||||
xobj->userCallback_->userarg(),
|
||||
*xobj->reqObj_,
|
||||
*xobj->resultData_,
|
||||
!finished);
|
||||
nHandled++;
|
||||
}
|
||||
} while(!done && !finished);
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * When no more data is ready, determine if the process is
|
||||
// * still alive.
|
||||
// *************************************************************
|
||||
if(!finished && waitpid(process, &stat_val, WNOHANG)==process &&
|
||||
(errno==ECHILD || WIFEXITED(stat_val)))
|
||||
{
|
||||
finished = 1;
|
||||
}
|
||||
}
|
||||
return nHandled;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptData::~ScriptData :
|
||||
// * The destructor is protected to prevent it from being deleted by
|
||||
// * anyone except the ScriptList class.
|
||||
// *****************************************************************************
|
||||
ScriptData::~ScriptData ( void )
|
||||
{
|
||||
static int killCount = 0;
|
||||
if(callbackCount==0)
|
||||
{
|
||||
data->remove();
|
||||
fireCallback (
|
||||
CDEV_SUCCESS,
|
||||
xobj->userCallback_->userarg(),
|
||||
*xobj->reqObj_,
|
||||
*data);
|
||||
}
|
||||
|
||||
if(inputBuf) delete inputBuf;
|
||||
if(sp.readFD != -1) close(sp.readFD);
|
||||
if(sp.writeFD != -1) close(sp.writeFD);
|
||||
if(data) delete data;
|
||||
if(xobj)
|
||||
{
|
||||
xobj->removeFromGrps();
|
||||
delete xobj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::ScriptList :
|
||||
// * This is the constructor for the ScriptList class. It
|
||||
// * initializes the internals of the class to 0.
|
||||
// *****************************************************************************
|
||||
ScriptList::ScriptList ( void ) : scripts(NULL), fdList(NULL), fdCount(0), fdMax(0)
|
||||
{
|
||||
};
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::ScriptList :
|
||||
// * This method will walk through the list of ScriptData objects and
|
||||
// * will delete each of them in sequence.
|
||||
// *
|
||||
// * Note that is no callbacks have been delivered for the specified
|
||||
// * ScriptData object, it will deliver a single callback with
|
||||
// * CDEV_ERROR as the status prior to terminating.
|
||||
// *****************************************************************************
|
||||
ScriptList::~ScriptList ( void )
|
||||
{
|
||||
ScriptData * curr;
|
||||
while(scripts!=NULL)
|
||||
{
|
||||
curr = scripts;
|
||||
scripts = scripts->next;
|
||||
delete curr;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::find :
|
||||
// * This method allows the caller to locate the ScriptData object
|
||||
// * that is associated with a specified file descriptor.
|
||||
// *****************************************************************************
|
||||
ScriptData * ScriptList::find ( int fd )
|
||||
{
|
||||
ScriptData * curr = scripts;
|
||||
while(curr->sp.readFD != fd && curr!=NULL)
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
return curr;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::insert :
|
||||
// * This method allows the caller to insert a new ScriptData object
|
||||
// * into the list of scripts that is managed by this list. Once
|
||||
// * added to the list the file descriptor associated with the
|
||||
// * ScriptData object will be placed on the list of file
|
||||
// * descriptors that will be polled by the cdevSystem object.
|
||||
// *****************************************************************************
|
||||
void ScriptList::insert ( ScriptData & script )
|
||||
{
|
||||
script.next = scripts;
|
||||
scripts = &script;
|
||||
|
||||
if(fdCount >= fdMax)
|
||||
{
|
||||
fdMax = (fdMax>1)?(fdMax*2):16;
|
||||
fdList = (int *)realloc(fdList, fdMax*sizeof(int));
|
||||
}
|
||||
if(fdCount==0) fdList[fdCount++] = selector.readfd();
|
||||
fdList[fdCount++] = script.sp.readFD;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::remove :
|
||||
// * This method calls the remove(fd) method to remove the ScriptData
|
||||
// * object that is specified by the caller.
|
||||
// *****************************************************************************
|
||||
void ScriptList::remove ( ScriptData & script )
|
||||
{
|
||||
remove(script.sp.readFD);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::remove :
|
||||
// * This method will walk through all scripts in the list until it
|
||||
// * locates the file descriptor specified by fd. The method will
|
||||
// * then remove the ScriptData object that is associated with that
|
||||
// * file descriptor.
|
||||
// *
|
||||
// * The fdList and fdCount variables will be updated once the dead
|
||||
// * file descriptor has been removed.
|
||||
// *****************************************************************************
|
||||
void ScriptList::remove ( int fd )
|
||||
{
|
||||
ScriptData * prev = NULL;
|
||||
ScriptData * curr = scripts;
|
||||
|
||||
while(curr!=NULL && curr->sp.readFD!=fd)
|
||||
{
|
||||
prev = curr;
|
||||
curr = prev->next;
|
||||
}
|
||||
if(curr!=NULL)
|
||||
{
|
||||
if(prev!=NULL) prev->next = curr->next;
|
||||
else scripts = curr->next;
|
||||
delete curr;
|
||||
|
||||
for(fdCount=0, curr = scripts; curr!=NULL; curr=curr->next)
|
||||
{
|
||||
fdList[fdCount++] = curr->sp.readFD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::getFd :
|
||||
// * This method allows the caller to obtain the list of file
|
||||
// * descriptors that are in use in all scripts. These descriptors
|
||||
// * will be used to perform ending at the cdevSystem level.
|
||||
// *
|
||||
// * Note that this list is updated and maintained each time the
|
||||
// * user calls "insert" to add a new file descriptor of "remove" to
|
||||
// * extract an old one.
|
||||
// *****************************************************************************
|
||||
int ScriptList::getFd ( int * &fd, int & numFd )
|
||||
{
|
||||
fd = fdList;
|
||||
numFd = fdCount;
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptList::poll :
|
||||
// * This method is called to poll for events on a list of scripts
|
||||
// * that are currently executing. This method will return the
|
||||
// * count of callbacks that were dispatched during this pass through
|
||||
// * poll.
|
||||
// *****************************************************************************
|
||||
int ScriptList::poll ( void )
|
||||
{
|
||||
int nHandled = 0;
|
||||
ScriptData * prev = NULL;
|
||||
ScriptData * curr = scripts;
|
||||
|
||||
// *********************************************************************
|
||||
// * Clear any events that might be stored in the selector object.
|
||||
// *********************************************************************
|
||||
selector.purge();
|
||||
|
||||
// *********************************************************************
|
||||
// * Walk through each script and call the dispatch method to
|
||||
// * fire callbacks for all file descriptors that have data
|
||||
// * ready.
|
||||
// *********************************************************************
|
||||
for(curr=scripts; curr!=NULL; curr = curr->next)
|
||||
{
|
||||
nHandled+=curr->dispatch();
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * Walk through the list of scripts again. This time, check
|
||||
// * the finished flag to determine if each script has run to
|
||||
// * completion. If so, remove the script from the list of
|
||||
// * scripts and delete it.
|
||||
// *********************************************************************
|
||||
for(prev=NULL, curr=scripts; curr!=NULL; )
|
||||
{
|
||||
if(curr->finished)
|
||||
{
|
||||
int deadFd = curr->sp.readFD;
|
||||
curr = curr->next;
|
||||
remove(deadFd);
|
||||
}
|
||||
else {
|
||||
prev = curr;
|
||||
curr = prev->next;
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * Return the total number of callbacks that were fired. This
|
||||
// * value will be used to allow for polling until at least one
|
||||
// * event has been processed.
|
||||
// *********************************************************************
|
||||
return nHandled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
* Continuous Electron Beam Accelerator Facility
|
||||
*
|
||||
* This software was developed under a United States Government license
|
||||
* described in the NOTICE file included as part of this distribution.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Description:
|
||||
* This header file contains the class definitions for the classes
|
||||
* associated with the construction of a script service.
|
||||
*
|
||||
* Author: Walt Akers
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <cdevData.h>
|
||||
#include <cdevTranObj.h>
|
||||
#include <cdevSelector.h>
|
||||
// *****************************************************************************
|
||||
// * class ScriptData :
|
||||
// * This contains the information associated with a single script. A list
|
||||
// * of ScriptData objects is maintained and accessed through the ScriptList
|
||||
// * object.
|
||||
// *
|
||||
// * Note: because this object is only accessed through the ScriptList
|
||||
// * object, all data items have been made public to improve performance.
|
||||
// *****************************************************************************
|
||||
class ScriptData
|
||||
{
|
||||
public:
|
||||
typedef struct {
|
||||
int readFD;
|
||||
int writeFD;
|
||||
} SocketPair;
|
||||
|
||||
|
||||
ScriptData * next;
|
||||
SocketPair sp;
|
||||
cdevTranObj * xobj;
|
||||
cdevData * data;
|
||||
char * inputBuf;
|
||||
int inputBufLen;
|
||||
int amntRead;
|
||||
pid_t process;
|
||||
int finished;
|
||||
int callbackCount;
|
||||
|
||||
ScriptData ( cdevTranObj & Xobj );
|
||||
~ScriptData (void);
|
||||
static int data2Buffer (cdevData & data, char *& buf, int &bufLen);
|
||||
static void dataArray2Buffer (char * output,
|
||||
char ** ptr,
|
||||
size_t & ptrIdx,
|
||||
cdevBounds * bounds,
|
||||
size_t nBounds,
|
||||
size_t boundsIdx);
|
||||
static void dataArray2Buffer (char * output,
|
||||
double * ptr,
|
||||
size_t & ptrIdx,
|
||||
cdevBounds * bounds,
|
||||
size_t nBounds,
|
||||
size_t boundsIdx);
|
||||
static int buffer2Data (char * &buf, cdevData & data );
|
||||
void fireCallback (int result,
|
||||
void * arg,
|
||||
cdevRequestObject &req,
|
||||
cdevData & data,
|
||||
int partial=0);
|
||||
int dispatch (void);
|
||||
};
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * class ScriptList:
|
||||
// * This class maintains a list of ScriptData objects that represent all
|
||||
// * of the scripts that are currently being run by the ScriptService. The
|
||||
// * ScriptService object will use the methods of this object to perform
|
||||
// * operations on the items in the list.
|
||||
// *
|
||||
// * Because this class is only accessible through the ScriptService, its
|
||||
// * internals have been made public to improve performance.
|
||||
// *****************************************************************************
|
||||
class ScriptList
|
||||
{
|
||||
public:
|
||||
static cdevSelector selector;
|
||||
|
||||
ScriptData * scripts;
|
||||
int * fdList;
|
||||
int fdCount;
|
||||
int fdMax;
|
||||
|
||||
ScriptList (void);
|
||||
~ScriptList (void);
|
||||
ScriptData * find ( int fd );
|
||||
void insert ( ScriptData & script );
|
||||
void remove ( ScriptData & script );
|
||||
void remove ( int fd );
|
||||
int getFd ( int * &fd, int & numFd );
|
||||
int poll ( void );
|
||||
};
|
||||
|
||||
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with the construction of a model request object.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
// Revision History:
|
||||
// ScriptRequestObject.cc,v
|
||||
// Revision 1.1 1997/02/11 17:37:24 akers
|
||||
// Directory restructure
|
||||
//
|
||||
// Revision 1.1 1997/01/30 20:35:34 akers
|
||||
// Initial installation of Script Service
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include <ScriptService.h>
|
||||
#include <ScriptRequestObject.h>
|
||||
#include <cdevClock.h>
|
||||
|
||||
int ScriptRequestObject::syncCode = 0;
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptRequestObject::ScriptRequestObject :
|
||||
// * This constructor initializes the internals of a device/message
|
||||
// * pair associated with the model server.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *********************************************************************
|
||||
ScriptRequestObject::ScriptRequestObject ( char * device, char * message, cdevSystem & system)
|
||||
: cdevRequestObject(device, message, system), syncFinished(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptRequestObject::sendNoBlock :
|
||||
// * This function allows the caller to submit an asynchronous message to the
|
||||
// * server for processing.
|
||||
// *****************************************************************************
|
||||
int ScriptRequestObject::sendNoBlock (cdevData * in, cdevData * out)
|
||||
{
|
||||
ScriptService * svc = (ScriptService *)service_;
|
||||
cdevTranObj * xobj = new cdevTranObj(&system_, this, out, &svc->asyncCallback);
|
||||
cdevData * Data = ((in==NULL)?new cdevData:new cdevData(*in));
|
||||
|
||||
return svc->submit(*xobj, *Data);
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptRequestObject::sendCallback :
|
||||
// * This function allows the caller to submit an asynchronous message to the
|
||||
// * server for processing.
|
||||
// *****************************************************************************
|
||||
int ScriptRequestObject::sendCallback (cdevData * in, cdevCallback & callback)
|
||||
{
|
||||
ScriptService * svc = (ScriptService *)service_;
|
||||
cdevTranObj * xobj = new cdevTranObj(&system_, this, NULL, new cdevCallback(callback));
|
||||
cdevData * Data = ((in==NULL)?new cdevData:new cdevData(*in));
|
||||
|
||||
xobj->enableDeleteCbk();
|
||||
return svc->submit(*xobj, *Data);
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptRequestObject::send :
|
||||
// * The send interface is used to provide synchronous I/O with the service.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int ScriptRequestObject::send ( cdevData * in, cdevData * out )
|
||||
{
|
||||
int status = CDEV_SUCCESS;
|
||||
ScriptService * svc = (ScriptService *)service_;
|
||||
cdevCallback * cb = new cdevCallback(ScriptService::syncCallbackFunc, (void *)++syncCode);
|
||||
cdevTranObj * xobj = new cdevTranObj(&system_, this, out, cb);
|
||||
cdevData * Data = ((in==NULL)?new cdevData:new cdevData(*in));
|
||||
|
||||
xobj->enableDeleteCbk();
|
||||
if((status = svc->submit(*xobj, *Data))==CDEV_SUCCESS)
|
||||
{
|
||||
// *************************************************************
|
||||
// * I used to wait for a response here only if the outbound
|
||||
// * cdevData object was non-null. However, that provided
|
||||
// * unexpected behavior to the client. Now I wait whether
|
||||
// * output data is expected or not.
|
||||
// *************************************************************
|
||||
cdevTimeValue t((double)SEND_WAIT_PERIOD);
|
||||
cdevClock timer;
|
||||
timer.schedule(NULL,t);
|
||||
|
||||
// *************************************************************
|
||||
// * WAITING WITH system_.pend():
|
||||
// * Previously I was using system_.pend() to process events
|
||||
// * while waiting for the service to respond. This resulted
|
||||
// * in a lock-up when the connection could not be
|
||||
// * established or if the connection collapsed while in use.
|
||||
// *
|
||||
// * WAITING WITH system_.poll():
|
||||
// * When in a heavy inbound traffic situation, the calls from other
|
||||
// * services will trample all over the inbound data coming from the
|
||||
// * model service. This results in unreliable delivery and
|
||||
// * processing of messages from the model server.
|
||||
// *
|
||||
// * WAITING WITH service_.poll():
|
||||
// * So far so good.
|
||||
// *************************************************************
|
||||
for(syncFinished=0; !syncFinished && !timer.expired(); svc->poll());
|
||||
if (!syncFinished)
|
||||
{
|
||||
status = CDEV_ERROR;
|
||||
system_.reportError(
|
||||
CDEV_SEVERITY_ERROR,
|
||||
"cdevRequestObject",
|
||||
this,
|
||||
"Transaction wasn't processed after %i seconds",
|
||||
SEND_WAIT_PERIOD);
|
||||
}
|
||||
else status = syncStatus;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
* Continuous Electron Beam Accelerator Facility
|
||||
*
|
||||
* This software was developed under a United States Government license
|
||||
* described in the NOTICE file included as part of this distribution.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Description:
|
||||
* This header file contains the class definitions for the classes
|
||||
* associated with the construction of a request object.
|
||||
*
|
||||
* Author: Walt Akers
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if !defined (_SCRIPT_REQUEST_OBJECT_H_)
|
||||
#define _SCRIPT_REQUEST_OBJECT_H_
|
||||
|
||||
#include <cdevRequestObject.h>
|
||||
#include <cdevTranObj.h>
|
||||
#include <cdevGroup.h>
|
||||
#include <cdevErrCode.h>
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptRequestObject:
|
||||
// * The ScriptRequestObject class provides the interface for sending
|
||||
// * messages to a server. All device/message commands are routed
|
||||
// * through a ScriptRequestObject either directly or indirectly.
|
||||
// *****************************************************************************
|
||||
class ScriptRequestObject : public cdevRequestObject
|
||||
{
|
||||
friend class ScriptService;
|
||||
|
||||
public:
|
||||
// *********************************************************************
|
||||
// * This is how long the system will wait for a reply to be returned
|
||||
// * from a send.
|
||||
// *********************************************************************
|
||||
enum { SEND_WAIT_PERIOD=30 };
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptRequestObject::ScriptRequestObject :
|
||||
// * This constructor initializes the internals of a device/message
|
||||
// * pair associated with the server.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *********************************************************************
|
||||
ScriptRequestObject ( char * device, char * message,
|
||||
cdevSystem & system = cdevSystem::defaultSystem() );
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptRequestObject::~ScriptRequestObject :
|
||||
// * This destructor performs any deallocation or shutdown operations
|
||||
// * necessary, prior to the destruction of the object.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *********************************************************************
|
||||
virtual ~ScriptRequestObject ( void ) {}
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptRequestObject::send :
|
||||
// * The send interface is used to provide synchronous I/O with the
|
||||
// * service.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int send ( cdevData & in, cdevData & out )
|
||||
{ return send(&in, &out); }
|
||||
int send ( cdevData * in, cdevData & out )
|
||||
{ return send(in, &out); }
|
||||
int send ( cdevData & in, cdevData * out )
|
||||
{ return send(&in, out); }
|
||||
int send ( cdevData * in, cdevData * out );
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptRequestObject::sendNoBlock :
|
||||
// * The sendNoBlock interface is used in conjunction with cdevGroup
|
||||
// * or cdevSystem to execute a series of operations. During the
|
||||
// * early implementation of this product, these functions will be
|
||||
// * linked directly to the send call.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int sendNoBlock (cdevData & in, cdevData & out)
|
||||
{ return sendNoBlock(&in, &out); }
|
||||
int sendNoBlock (cdevData * in, cdevData & out)
|
||||
{ return sendNoBlock(in, &out); }
|
||||
int sendNoBlock (cdevData & in, cdevData * out)
|
||||
{ return sendNoBlock(&in, out); }
|
||||
int sendNoBlock (cdevData * in, cdevData * out);
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptRequestObject::sendCallback :
|
||||
// * The sendCallback interface provides asynchronous communications
|
||||
// * with the server. During the early implementation of this
|
||||
// * product, these functions will be linked directly to the send
|
||||
// * call.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int sendCallback (cdevData & in, cdevCallback & callback)
|
||||
{ return sendCallback(&in, callback); }
|
||||
int sendCallback (cdevData * in, cdevCallback & callback);
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptRequestObject::className :
|
||||
// * This function returns the name of the class as a constant string
|
||||
// *********************************************************************
|
||||
const char * className ( void ) const { return "ScriptRequestObject"; }
|
||||
|
||||
private:
|
||||
int syncFinished;
|
||||
int syncStatus;
|
||||
static int syncCode;
|
||||
};
|
||||
|
||||
#endif /* _SCRIPT_REQUEST_OBJECT_H_ */
|
||||
+381
@@ -0,0 +1,381 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with the construction of a script service.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
// Revision History:
|
||||
// ScriptService.cc,v
|
||||
// Revision 1.3 1997/02/14 20:43:41 akers
|
||||
// Ongoing improvement
|
||||
//
|
||||
// Revision 1.2 1997/02/14 20:06:32 akers
|
||||
// Ongoing improvement
|
||||
//
|
||||
// Revision 1.1 1997/02/11 17:37:27 akers
|
||||
// Directory restructure
|
||||
//
|
||||
// Revision 1.3 1997/01/31 18:51:27 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.2 1997/01/31 16:21:24 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.1 1997/01/30 20:35:35 akers
|
||||
// Initial installation of Script Service
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "ScriptService.h"
|
||||
#include "cdevDirectory.h"
|
||||
#include "cdevClock.h"
|
||||
#include "ScriptList.h"
|
||||
|
||||
cdevSelector ScriptList::selector;
|
||||
|
||||
// ****************************************************************************
|
||||
// * This function is an interrupt handler that will be executed whenever the
|
||||
// * program receives a SIGCHLD signal. When called it will execute the poll
|
||||
// * method of the default server, in order to remove any dead Script Service
|
||||
// * processes.
|
||||
// ****************************************************************************
|
||||
static void SIGCHLD_handler (int)
|
||||
{
|
||||
ScriptList::selector.insertEvent();
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// * newScriptService :
|
||||
// * This method is called by the cdevSystem object to load the
|
||||
// * initial instance of the ScriptService.
|
||||
// *********************************************************************
|
||||
cdevService * newScriptService ( char * name, cdevSystem * system )
|
||||
{
|
||||
signal(SIGCHLD, SIGCHLD_handler);
|
||||
return new ScriptService(name, *system);
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::ScriptService :
|
||||
// * This is the constructor for the script service. It determines
|
||||
// * the tag number for the "filename" tag if it does not already
|
||||
// * exist and allocates the ScriptList object that will be used
|
||||
// * to hold the individual script instances.
|
||||
// *********************************************************************
|
||||
ScriptService::ScriptService ( char * name, cdevSystem & system )
|
||||
: cdevService(name, system),
|
||||
FILENAME_TAG(1000),
|
||||
asyncCallback(asyncCallbackFunc, NULL)
|
||||
{
|
||||
scripts = new ScriptList;
|
||||
|
||||
while(cdevData::tagC2I("filename", &FILENAME_TAG)!=CDEV_SUCCESS)
|
||||
{
|
||||
cdevData::insertTag(++FILENAME_TAG, "filename");
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::~ScriptService :
|
||||
// * This is the destructor for the script service,it does nothing
|
||||
// * but act as a placeholder for the virtual destructor.
|
||||
// *********************************************************************
|
||||
ScriptService::~ScriptService ( void )
|
||||
{
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::getRequestObject :
|
||||
// * This is the interface that cdev objects will use to obtain a
|
||||
// * ScriptRequestObject object. The ScriptRequestObject
|
||||
// * represents a combined device and message pair that is associated
|
||||
// * with the ScriptService.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int ScriptService::getRequestObject ( char * device, char * message, cdevRequestObject * &req)
|
||||
{
|
||||
req = new ScriptRequestObject (device, message, system_);
|
||||
return (req ? CDEV_SUCCESS : CDEV_ERROR);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptService::getFd
|
||||
// * This function will return the list of file descriptors that the
|
||||
// * ScriptService is using. This will allow the file descriptors to be
|
||||
// * used in global select and poll calls performed at the cdevSystem class
|
||||
// * level.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int ScriptService::getFd ( int * &fd, int & numFd )
|
||||
{
|
||||
fd = scripts->fdList;
|
||||
numFd = scripts->fdCount;
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::flush :
|
||||
// * This function flushes all communications buffers that the
|
||||
// * service may have open.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int ScriptService::flush ( void )
|
||||
{
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptService::poll :
|
||||
// * This function polls the file descriptors used by the service
|
||||
// * until one of them becomes active or a discrete amount of time
|
||||
// * has expired.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int ScriptService::poll ( void )
|
||||
{
|
||||
if(scripts->fdCount>0) scripts->poll();
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptService::pend :
|
||||
// * Pends until the named file descriptor (or any file descriptor
|
||||
// * if fd = -1) is ready. Will pend forever if the descriptor does
|
||||
// * not become active.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int ScriptService::pend ( int )
|
||||
{
|
||||
while(scripts->fdCount>0 && scripts->poll()==0);
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptService::pend :
|
||||
// * Pends until the named file descriptor (or any file descriptor
|
||||
// * if fd = -1) is ready. Will pend for no longer than the user
|
||||
// * specified number of seconds.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int ScriptService::pend ( double seconds, int )
|
||||
{
|
||||
if(scripts->fdCount > 0)
|
||||
{
|
||||
int nHandled = 0;
|
||||
cdevTimeValue sec = seconds;
|
||||
cdevClock timer;
|
||||
|
||||
timer.schedule(NULL, sec);
|
||||
|
||||
do {
|
||||
nHandled = scripts->poll();
|
||||
} while(!nHandled &&
|
||||
!timer.expired() &&
|
||||
scripts->fdCount>0);
|
||||
}
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptService::submit :
|
||||
// * This is the mechanism that the request object will use to submit a
|
||||
// * message to the service. It is important to note that all of the
|
||||
// * data provided to this object becomes the property of the service and
|
||||
// * must not be accessed afterwords.
|
||||
// *****************************************************************************
|
||||
int ScriptService::submit ( cdevTranObj &xobj, cdevData &data )
|
||||
{
|
||||
int status = CDEV_SUCCESS;
|
||||
|
||||
// *********************************************************************
|
||||
// * Attempt to read the script filename from the DDL file.
|
||||
// *********************************************************************
|
||||
ScriptData *script = new ScriptData(xobj);
|
||||
cdevData temp;
|
||||
char DDL_request[256];
|
||||
|
||||
sprintf (DDL_request,
|
||||
"resolveServiceData %s %s",
|
||||
xobj.reqObj_->device().name(),
|
||||
xobj.reqObj_->message());
|
||||
|
||||
if((system_.nameServer()).send(DDL_request, NULL, &temp)==CDEV_SUCCESS)
|
||||
{
|
||||
*DDL_request = 0;
|
||||
temp.get (FILENAME_TAG, DDL_request, 256);
|
||||
}
|
||||
else *DDL_request = 0;
|
||||
|
||||
// *********************************************************************
|
||||
// * If the script file was loaded, then begin the process of creating
|
||||
// * a pipe to retrieve the output of the script, and forking off an
|
||||
// * additional process to handle execution.
|
||||
// *********************************************************************
|
||||
if(*DDL_request)
|
||||
{
|
||||
char * parms = NULL;
|
||||
int bufLen = 0;
|
||||
|
||||
// *************************************************************
|
||||
// * Extract the data from the user provided output cdevData
|
||||
// * object into a string that can be passed to the script.
|
||||
// *************************************************************
|
||||
ScriptData::data2Buffer(data, parms, bufLen);
|
||||
|
||||
// *************************************************************
|
||||
// * Make a copy standard output for later use to restore the
|
||||
// * standard output file descriptor in the main thread...
|
||||
// * This is because the behaviour of vfork on some systems
|
||||
// * will leave the file descriptor in the main thread modified.
|
||||
// *************************************************************
|
||||
int fd = dup(1);
|
||||
|
||||
// *************************************************************
|
||||
// * Set the standard output file descriptor to the write file
|
||||
// * descriptor of the socket pair.
|
||||
// *************************************************************
|
||||
dup2(script->sp.writeFD, 1);
|
||||
|
||||
// *************************************************************
|
||||
// * Fork the process to allow the user application to continue
|
||||
// * running in the original branch, and the script to be
|
||||
// * executed in the new (child) process.
|
||||
// *************************************************************
|
||||
switch((script->process = vfork()))
|
||||
{
|
||||
// *****************************************************
|
||||
// * 0 Indicates that we are in the new child process.
|
||||
// *****************************************************
|
||||
case 0:
|
||||
{
|
||||
if(bufLen)
|
||||
{
|
||||
execl(DDL_request,
|
||||
DDL_request,
|
||||
xobj.reqObj_->device().name(),
|
||||
xobj.reqObj_->message(),
|
||||
parms, NULL);
|
||||
}
|
||||
else {
|
||||
execl(DDL_request,
|
||||
DDL_request,
|
||||
xobj.reqObj_->device().name(),
|
||||
xobj.reqObj_->message(),
|
||||
NULL);
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
|
||||
// *****************************************************
|
||||
// * -1 Indicates that a new process could not be
|
||||
// * forked.
|
||||
// *****************************************************
|
||||
case -1:
|
||||
{
|
||||
// *********************************************
|
||||
// * Restore the standard output file descriptor
|
||||
// *********************************************
|
||||
dup2(fd, 1);
|
||||
close(fd);
|
||||
|
||||
system_.reportError(
|
||||
CDEV_SEVERITY_ERROR,
|
||||
"ScriptService",
|
||||
xobj.reqObj_,
|
||||
"Failed to fork a new process");
|
||||
|
||||
script->fireCallback(CDEV_ERROR,
|
||||
xobj.userCallback_->userarg(),
|
||||
*xobj.reqObj_,
|
||||
*script->data);
|
||||
|
||||
status = CDEV_ERROR;
|
||||
delete script;
|
||||
}
|
||||
break;
|
||||
|
||||
// *****************************************************
|
||||
// * Any other value indicates that we are in the parent
|
||||
// * and the value is the process ID of the new child.
|
||||
// *****************************************************
|
||||
default:
|
||||
{
|
||||
// *********************************************
|
||||
// * Restore the standard output file descriptor
|
||||
// *********************************************
|
||||
dup2(fd, 1);
|
||||
close(fd);
|
||||
|
||||
// *********************************************
|
||||
// * Insert the script into the list.
|
||||
// *********************************************
|
||||
scripts->insert(*script);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * Delete parameters (if any).
|
||||
// *************************************************************
|
||||
if(bufLen) delete parms;
|
||||
}
|
||||
else {
|
||||
system_.reportError(
|
||||
CDEV_SEVERITY_ERROR,
|
||||
"ScriptService",
|
||||
xobj.reqObj_,
|
||||
"No filename specified for request %s %s",
|
||||
xobj.reqObj_->device().name(),
|
||||
xobj.reqObj_->message());
|
||||
|
||||
script->fireCallback(CDEV_ERROR,
|
||||
xobj.userCallback_->userarg(),
|
||||
*xobj.reqObj_,
|
||||
*script->data);
|
||||
status = CDEV_ERROR;
|
||||
delete script;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ScriptService::getNameServer :
|
||||
// * This function should obtain the default name server for this object.
|
||||
// * It does nothing for now.
|
||||
// *****************************************************************************
|
||||
int ScriptService::getNameServer(cdevDevice * &ns)
|
||||
{
|
||||
ns = 0;
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
Executable
+166
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
* Continuous Electron Beam Accelerator Facility
|
||||
*
|
||||
* This software was developed under a United States Government license
|
||||
* described in the NOTICE file included as part of this distribution.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* Description:
|
||||
* This header file contains the class definitions for the classes
|
||||
* associated with the construction of a script service.
|
||||
*
|
||||
* Author: Walt Akers
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if !defined (_SCRIPT_SERVICE_H_)
|
||||
#define _SCRIPT_SERVICE_H_
|
||||
|
||||
#include <cdevService.h>
|
||||
#include "ScriptRequestObject.h"
|
||||
|
||||
extern "C" cdevService *newScriptService ( char * name, cdevSystem * system );
|
||||
|
||||
class ScriptService : public cdevService
|
||||
{
|
||||
friend class ScriptRequestObject;
|
||||
|
||||
public:
|
||||
// *********************************************************************
|
||||
// * ScriptService::ScriptService :
|
||||
// * This constructor is responsible for performing all service
|
||||
// * initialization.
|
||||
// *********************************************************************
|
||||
ScriptService ( char * name, cdevSystem & system );
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::~ScriptService :
|
||||
// * The destructor is protected to prevent it from being called
|
||||
// * directly. The destructor performs any clean-up or shutdown
|
||||
// * operations.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *********************************************************************
|
||||
~ScriptService ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::installTags :
|
||||
// * Installs the tags that the service and service applications
|
||||
// * will use. This function is static to allow servers to setup
|
||||
// * the necessary tags without having to instanciate a
|
||||
// * ScriptService object.
|
||||
// *********************************************************************
|
||||
void installTags ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::getRequestObject :
|
||||
// * This is the interface that cdev objects will use to obtain a
|
||||
// * cdevSimpleRequestObject object. The cdevSimpleRequestObject
|
||||
// * represents a combined device and message pair that is associated
|
||||
// * with the ScriptService.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int getRequestObject (char *, char *, cdevRequestObject * &);
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::getFd
|
||||
// * This function will return the list of file descriptors that the
|
||||
// * ScriptService is using. This will allow the file
|
||||
// * descriptors to be used in global select and poll calls performed
|
||||
// * at the cdevSystem class level.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int getFd ( int * &fd, int & numFd );
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::flush :
|
||||
// * This function flushes all communications buffers that the
|
||||
// * service may have open.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int flush ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::poll :
|
||||
// * This function polls the file descriptors used by the service
|
||||
// * until one of them becomes active or a discrete amount of time
|
||||
// * has expired.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int poll ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::pend :
|
||||
// * Pends until the named file descriptor (or any file descriptor
|
||||
// * if fd = -1) is ready. Will pend for no longer than the user
|
||||
// * specified number of seconds.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int pend ( double seconds, int = -1);
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::pend :
|
||||
// * Pends until the named file descriptor (or any file descriptor
|
||||
// * if fd = -1) is ready. Will pend forever if the descriptor does
|
||||
// * not become active.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int pend ( int = -1);
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::submit :
|
||||
// * This is the mechanism that the request object will use to submit
|
||||
// * a message to the service. It is important to note that all of
|
||||
// * the data provided to this object becomes the property of the
|
||||
// * service and must not be accessed afterwords.
|
||||
// *********************************************************************
|
||||
int submit (cdevTranObj &, cdevData &);
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::getNameServer :
|
||||
// * This function should obtain the default name server for this
|
||||
// * object. It does nothing for now.
|
||||
// *********************************************************************
|
||||
int getNameServer(cdevDevice * &ns);
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::asyncCallback :
|
||||
// * This method is called in response to a sendNoBlock reply.
|
||||
// *********************************************************************
|
||||
static void asyncCallbackFunc (int, void *, cdevRequestObject &, cdevData &)
|
||||
{
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * ScriptService::syncCallback :
|
||||
// * This method is called whenever a send is requested from a
|
||||
// * ScriptRequestObject.
|
||||
// *********************************************************************
|
||||
static void syncCallbackFunc ( int status, void *arg, cdevRequestObject &req, cdevData &)
|
||||
{
|
||||
ScriptRequestObject * sReq = (ScriptRequestObject *)&req;
|
||||
int syncCode = (int)arg;
|
||||
|
||||
if(syncCode == sReq->syncCode)
|
||||
{
|
||||
sReq->syncFinished = 1;
|
||||
sReq->syncStatus = status;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
int FILENAME_TAG;
|
||||
class ScriptList * scripts;
|
||||
cdevCallback asyncCallback;
|
||||
};
|
||||
|
||||
#endif /* _SCRIPT_SERVICE_H_ */
|
||||
Binary file not shown.
Binary file not shown.
Executable
+39
@@ -0,0 +1,39 @@
|
||||
ARCH = OS
|
||||
SHOBJ = YES
|
||||
|
||||
include $(CDEV)/extensions/cdevGenericServer/include/makeinclude/Makefile.$(ARCH)
|
||||
|
||||
APPNAME = "CDEV/ACE Script Service Tests"
|
||||
CXXINCLUDES = -I./
|
||||
BASEBIN = ./
|
||||
SO_LIBS = $(OSLIBS)
|
||||
|
||||
# ******************************************************************************
|
||||
# * The BINARIES definition names all of the binary files that should be deleted
|
||||
# * whenever "make clean" is executed.
|
||||
# ******************************************************************************
|
||||
BINARIES = $(BASEBIN)/TestProgram $(BASEBIN)/TestProgram2
|
||||
|
||||
ifeq ($(SHOBJ), YES)
|
||||
LIBS = $(CDEVLIBS) $(OSLIBS)
|
||||
TARGETS = $(BASEBIN)/TestProgram \
|
||||
$(BASEBIN)/TestProgram2
|
||||
else
|
||||
LIBS = $(CDEVLIBS) -lScriptService $(OSLIBS)
|
||||
TARGETS = $(BASEBIN)/TestProgram \
|
||||
$(BASEBIN)/TestProgram2
|
||||
endif
|
||||
|
||||
targets : $(TARGETS)
|
||||
|
||||
$(BASEBIN)/TestProgram : $(OBJDIR)/TestProgram.o
|
||||
@rm -f $@
|
||||
@echo "=> $(CXX) -o $(@F) $(^F)"
|
||||
@$(LINK.cc) $^ -o $@ $(LIBS)
|
||||
@echo "<= Done...\n"
|
||||
|
||||
$(BASEBIN)/TestProgram2 : $(OBJDIR)/TestProgram2.o
|
||||
@rm -f $@
|
||||
@echo "=> $(CXX) -o $(@F) $(^F)"
|
||||
@$(LINK.cc) $^ -o $@ $(LIBS)
|
||||
@echo "<= Done...\n"
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
service Script
|
||||
{
|
||||
tags {filename}
|
||||
}
|
||||
|
||||
class scriptClass
|
||||
{
|
||||
verbs {get, set, monitorOn, monitorOff}
|
||||
attributes
|
||||
{
|
||||
attrib0 Script {filename = <>.attrib0};
|
||||
attrib1 Script {filename = <>.attrib1};
|
||||
attrib2 Script {filename = <>.attrib2};
|
||||
attrib3 Script {filename = <>.attrib3};
|
||||
attrib4 Script {filename = <>.attrib4};
|
||||
attrib5 Script {filename = <>.attrib5};
|
||||
attrib6 Script {filename = <>.attrib6};
|
||||
attrib7 Script {filename = <>.attrib7};
|
||||
attrib8 Script {filename = <>.attrib8};
|
||||
attrib9 Script;
|
||||
}
|
||||
}
|
||||
|
||||
scriptClass :
|
||||
device0, device1, device2, device3, device4,
|
||||
device5, device6, device7, device8, device9
|
||||
;
|
||||
Executable
BIN
Binary file not shown.
Executable
+76
@@ -0,0 +1,76 @@
|
||||
#include <cdevSystem.h>
|
||||
#include <cdevRequestObject.h>
|
||||
#include <cdevCallback.h>
|
||||
#include <cdevGroup.h>
|
||||
|
||||
void callback (int, void *arg, cdevRequestObject &, cdevData &)
|
||||
{
|
||||
static int totalCount = 0;
|
||||
int * resultCount = (int *)arg;
|
||||
(*resultCount)++;
|
||||
|
||||
fprintf(stdout, "Total count = %i\n", ++totalCount);
|
||||
}
|
||||
|
||||
char * data[2][2][3] =
|
||||
{
|
||||
{{"1", "2", "3"}, {"4", "5", "6"}},
|
||||
{{"1", "2", "3"}, {"4", "5", "6"}},
|
||||
};
|
||||
|
||||
double dData[2][2][3] =
|
||||
{
|
||||
{{1.1, 2.2, 3.3}, {4.4, 5.5, 6.6}},
|
||||
{{1.7, 2.8, 3.9}, {4.11, 5.12, 6.13}}
|
||||
};
|
||||
|
||||
cdevBounds bounds[3] =
|
||||
{{0, 2},
|
||||
{0, 2},
|
||||
{0, 3}};
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
int resultCount = 0;
|
||||
cdevData in;
|
||||
cdevRequestObject & req = cdevRequestObject::attachRef("device0", "get attrib0");
|
||||
cdevCallback cb (callback, &resultCount);
|
||||
|
||||
in.insert("value", (char **)data, 12, 3);
|
||||
in.setBounds("value", bounds, 3);
|
||||
in.insert("severity", (double*)dData, 12, 3);
|
||||
in.setBounds("severity", bounds, 3);
|
||||
in.insert("status", "Testing");
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
resultCount = 0;
|
||||
|
||||
for(int j=0; j<20; j++)
|
||||
{
|
||||
req.sendCallback(in, cb);
|
||||
}
|
||||
while(resultCount<26) cdevSystem::defaultSystem().poll();
|
||||
}
|
||||
}
|
||||
/*
|
||||
#include "ScriptList.cc"
|
||||
|
||||
int main()
|
||||
{
|
||||
cdevData in, out;
|
||||
char * buf;
|
||||
int bufLen;
|
||||
|
||||
in.insert("value", (char **)data, 12, 3);
|
||||
in.setBounds("value", bounds, 3);
|
||||
in.insert("severity", (double*)dData, 12, 3);
|
||||
in.setBounds("severity", bounds, 3);
|
||||
in.insert("status", "Testing");
|
||||
|
||||
ScriptData::data2Buffer(in, buf, bufLen);
|
||||
ScriptData::buffer2Data(buf, out);
|
||||
out.asciiDump();
|
||||
delete buf;
|
||||
}
|
||||
*/
|
||||
Executable
BIN
Binary file not shown.
+27
@@ -0,0 +1,27 @@
|
||||
#include <cdevSystem.h>
|
||||
#include <cdevRequestObject.h>
|
||||
#include <cdevCallback.h>
|
||||
#include <cdevGroup.h>
|
||||
|
||||
int done = 0;
|
||||
|
||||
void callback (int, void *, cdevRequestObject &, cdevData &data)
|
||||
{
|
||||
static int resultCount = 0;
|
||||
done = cdevCallback::isTransactionDone();
|
||||
fprintf(stdout, "Result count %i - %s done...\n", ++resultCount, done?" ":"NOT");
|
||||
if(done) data.asciiDump();
|
||||
}
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
cdevData in;
|
||||
cdevRequestObject & req = cdevRequestObject::attachRef("device0", "get attrib0");
|
||||
cdevCallback cb (callback, NULL);
|
||||
|
||||
req.sendCallback(in, cb);
|
||||
while(!done)
|
||||
{
|
||||
cdevSystem::defaultSystem().pend();
|
||||
}
|
||||
}
|
||||
+386
@@ -0,0 +1,386 @@
|
||||
#! /bin/csh -f
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value=1\nseverity="GOOD"\nstatus=0\nend\n'
|
||||
printf 'value={{1,2,3},{4,5,6}}\nseverity="NOT so GOOD"\nstatus=0\ncontrolLow={1, 2, 3}\ndone\n'
|
||||
+1
@@ -0,0 +1 @@
|
||||
#! /bin/csh
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
load /lib/milli.a
|
||||
load /lib/libc.sl
|
||||
load /usr/csite4/CenterLine/pa-hpux8/lib/libC.a
|
||||
load -G /usr/csite/cdev/1.5/lib/hpux-09.XX/libcdev.a
|
||||
load -D_OS_MAJOR_=9 \
|
||||
-D_OS_MINOR_=7 \
|
||||
-I/usr/csite/cdev/1.5/include \
|
||||
-g -D_HAS_CA -pta \
|
||||
-I./ -I../src\
|
||||
../src/ScriptList.cc \
|
||||
../src/ScriptService.cc \
|
||||
../src/ScriptRequestObject.cc \
|
||||
TestProgram2.cc \
|
||||
-ly -ll -L/lib -lm
|
||||
link
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
+43
@@ -0,0 +1,43 @@
|
||||
ARCH=OS
|
||||
include ../cdevGenericServer/include/makeinclude/Makefile.$(ARCH)
|
||||
|
||||
APPNAME = "CDEV Simple Generic Service"
|
||||
BASEDIR = $(shell pwd)
|
||||
INCDIR = $(CDEV)/extensions/cdevGenericServer/include
|
||||
BINDIR = ./
|
||||
LIBDIR = $(CDEV)/lib/$(TARGETDIR)
|
||||
|
||||
CDEV_INCLUDES = -I$(CDEV)/include
|
||||
CDEV_LIBS = -lcdev
|
||||
CDEV_LIBDIR = $(CDEV)/lib/$(TARGETDIR)
|
||||
|
||||
CLASS_INCLUDES = -I./ -I$(INCDIR)
|
||||
|
||||
CXXEXTRA = -g $(CDEV_INCLUDES) $(CLASS_INCLUDES)
|
||||
|
||||
ARLIB_OBJ = .obj/$(TARGETDIR)/cdevSimpleRequestObject.o \
|
||||
.obj/$(TARGETDIR)/cdevSimpleService.o \
|
||||
.obj/$(TARGETDIR)/cdevTranNode.o
|
||||
|
||||
SHLIB_OBJ = .shobj/$(TARGETDIR)/cdevSimpleRequestObject.o \
|
||||
.shobj/$(TARGETDIR)/cdevSimpleService.o \
|
||||
.shobj/$(TARGETDIR)/cdevTranNode.o
|
||||
|
||||
TARGETS = $(LIBDIR)/libSimpleService.a $(LIBDIR)/libSimpleService.sl
|
||||
|
||||
targets : $(TARGETS)
|
||||
|
||||
$(LIBDIR)/libSimpleService.a : $(ARLIB_OBJ)
|
||||
@rm -f $@
|
||||
@echo "=> ar ruv $@"
|
||||
@mkdir -p $(LIBDIR)
|
||||
@$(LINK.a) $@ $(ARLIB_OBJ)
|
||||
@ranlib $@ > /dev/null
|
||||
@echo "\n -------- Completed ----------\n"
|
||||
|
||||
$(LIBDIR)/libSimpleService.sl : $(SHLIB_OBJ)
|
||||
@rm -f $@
|
||||
@echo "=> $(LINK.so) $(@F)"
|
||||
@mkdir -p $(LIBDIR)
|
||||
@$(LINK.so) -o $@ $(SHLIB_OBJ)
|
||||
@echo "\n -------- Completed ----------\n"
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with the construction of a model request object.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
// Revision History:
|
||||
// cdevSimpleRequestObject.cc,v
|
||||
// Revision 1.1 1996/11/21 18:22:19 akers
|
||||
// Non-Server Oriented Service
|
||||
//
|
||||
// Revision 1.1 1996/04/30 15:37:30 akers
|
||||
// Simple CDEV Service
|
||||
//
|
||||
// Revision 1.1.1.1 1996/02/28 16:36:21 akers
|
||||
// Initial release of support for ACE Services
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include <cdevSimpleService.h>
|
||||
#include <cdevSimpleRequestObject.h>
|
||||
#include <cdevClock.h>
|
||||
#include <cdevTranNode.h>
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleRequestObject::cdevSimpleRequestObject :
|
||||
// * This constructor initializes the internals of a device/message
|
||||
// * pair associated with the model server.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *********************************************************************
|
||||
cdevSimpleRequestObject::cdevSimpleRequestObject ( char * device, char * message, cdevSystem & system)
|
||||
: cdevRequestObject(device, message, system)
|
||||
{
|
||||
cdevData::tagC2I("transaction", &TRANSACT_TAG);
|
||||
cdevData::tagC2I("transobject", &TRANSOBJ_TAG);
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleRequestObject::sendNoBlock :
|
||||
// * This function allows the caller to submit an asynchronous message to the
|
||||
// * server for processing.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleRequestObject::sendNoBlock (cdevData * in, cdevData * out)
|
||||
{
|
||||
cdevSimpleService * svc = (cdevSimpleService *)service_;
|
||||
cdevTranNode * xobj = new cdevTranNode(&system_, this, out, &svc->callback);
|
||||
char * Device = strdup(deviceName_);
|
||||
char * Message = strdup(message_);
|
||||
cdevData * Data = ((in==NULL)?new cdevData:new cdevData(*in));
|
||||
|
||||
svc->submit(xobj, Device, Message, Data);
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleRequestObject::sendCallback :
|
||||
// * This function allows the caller to submit an asynchronous message to the
|
||||
// * server for processing.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleRequestObject::sendCallback (cdevData * in, cdevCallback & callback)
|
||||
{
|
||||
cdevSimpleService * svc = (cdevSimpleService *)service_;
|
||||
cdevTranNode * xobj = new cdevTranNode(&system_, this, NULL, new cdevCallback(callback));
|
||||
char * Device = strdup(deviceName_);
|
||||
char * Message = strdup(message_);
|
||||
cdevData * Data = ((in==NULL)?new cdevData:new cdevData(*in));
|
||||
|
||||
xobj->enableDeleteCbk();
|
||||
svc->submit(xobj, Device, Message, Data);
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleRequestObject::send :
|
||||
// * The send interface is used to provide synchronous I/O with the service.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleRequestObject::send ( cdevData * in, cdevData * out )
|
||||
{
|
||||
int status = CDEV_SUCCESS;
|
||||
cdevSimpleService * svc = (cdevSimpleService *)service_;
|
||||
cdevTranNode * xobj = new cdevTranNode(&system_, this, out, &svc->callback);
|
||||
char * Device = strdup(deviceName_);
|
||||
char * Message = strdup(message_);
|
||||
cdevData * Data = ((in==NULL)?new cdevData:new cdevData(*in));
|
||||
|
||||
xobj->permanent(1);
|
||||
svc->submit(xobj, Device, Message, Data);
|
||||
|
||||
// *********************************************************************
|
||||
// * I used to wait for a response here only if the outbound cdevData
|
||||
// * object was non-null. However, that provided unexpected behavior
|
||||
// * to the client. Now I wait whether output data is expected or not.
|
||||
// *********************************************************************
|
||||
cdevTimeValue t(30.0);
|
||||
cdevClock timer;
|
||||
timer.schedule(NULL,t);
|
||||
|
||||
// *********************************************************************
|
||||
// * WAITING WITH system_.pend():
|
||||
// * Previously I was using system_.pend() to process events while
|
||||
// * waiting for the service to respond. This resulted in a lock-up
|
||||
// * when the connection could not be established or if the
|
||||
// * connection collapsed while in use.
|
||||
// *
|
||||
// * WAITING WITH system_.poll():
|
||||
// * When in a heavy inbound traffic situation, the calls from other
|
||||
// * services will trample all over the inbound data coming from the
|
||||
// * model service. This results in unreliable delivery and
|
||||
// * processing of messages from the model server.
|
||||
// *
|
||||
// * WAITING WITH service_.poll():
|
||||
// * So far so good.
|
||||
// *********************************************************************
|
||||
while(!xobj->finished() && !timer.expired()) service_->poll();
|
||||
if (!xobj->finished())
|
||||
{
|
||||
status = CDEV_ERROR;
|
||||
system_.reportError(
|
||||
CDEV_SEVERITY_ERROR,
|
||||
"cdevRequestObject",
|
||||
this,
|
||||
"Transaction wasn't processed after 30 seconds");
|
||||
}
|
||||
|
||||
delete xobj;
|
||||
return status;
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with the construction of a request object.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if !defined (_CDEV_SIMPLE_REQUEST_OBJECT_H_)
|
||||
#define _CDEV_SIMPLE_REQUEST_OBJECT_H_
|
||||
|
||||
#include <cdevRequestObject.h>
|
||||
#include <cdevTranObj.h>
|
||||
#include <cdevGroup.h>
|
||||
#include <cdevErrCode.h>
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleRequestObject:
|
||||
// * The cdevSimpleRequestObject class provides the interface for sending
|
||||
// * messages to a server. All device/message commands are routed
|
||||
// * through a cdevSimpleRequestObject either directly or indirectly.
|
||||
// *****************************************************************************
|
||||
class cdevSimpleRequestObject : public cdevRequestObject
|
||||
{
|
||||
public:
|
||||
// *********************************************************************
|
||||
// * cdevSimpleRequestObject::cdevSimpleRequestObject :
|
||||
// * This constructor initializes the internals of a device/message
|
||||
// * pair associated with the server.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *********************************************************************
|
||||
cdevSimpleRequestObject ( char * device, char * message,
|
||||
cdevSystem & system = cdevSystem::defaultSystem() );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleRequestObject::~cdevSimpleRequestObject :
|
||||
// * This destructor performs any deallocation or shutdown operations
|
||||
// * necessary, prior to the destruction of the object.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *********************************************************************
|
||||
~cdevSimpleRequestObject ( void ) {}
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleRequestObject::send :
|
||||
// * The send interface is used to provide synchronous I/O with the
|
||||
// * service.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int send ( cdevData & in, cdevData & out )
|
||||
{ return send(&in, &out); }
|
||||
int send ( cdevData * in, cdevData & out )
|
||||
{ return send(in, &out); }
|
||||
int send ( cdevData & in, cdevData * out )
|
||||
{ return send(&in, out); }
|
||||
int send ( cdevData * in, cdevData * out );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleRequestObject::sendNoBlock :
|
||||
// * The sendNoBlock interface is used in conjunction with cdevGroup
|
||||
// * or cdevSystem to execute a series of operations. During the
|
||||
// * early implementation of this product, these functions will be
|
||||
// * linked directly to the send call.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int sendNoBlock (cdevData & in, cdevData & out)
|
||||
{ return sendNoBlock(&in, &out); }
|
||||
int sendNoBlock (cdevData * in, cdevData & out)
|
||||
{ return sendNoBlock(in, &out); }
|
||||
int sendNoBlock (cdevData & in, cdevData * out)
|
||||
{ return sendNoBlock(&in, out); }
|
||||
int sendNoBlock (cdevData * in, cdevData * out);
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleRequestObject::sendCallback :
|
||||
// * The sendCallback interface provides asynchronous communications
|
||||
// * with the server. During the early implementation of this
|
||||
// * product, these functions will be linked directly to the send
|
||||
// * call.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int sendCallback (cdevData & in, cdevCallback & callback)
|
||||
{ return sendCallback(&in, callback); }
|
||||
int sendCallback (cdevData * in, cdevCallback & callback);
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleRequestObject::className :
|
||||
// * This function returns the name of the class as a constant string
|
||||
// *********************************************************************
|
||||
const char * className ( void ) const { return "cdevSimpleRequestObject"; }
|
||||
|
||||
private:
|
||||
int TRANSACT_TAG;
|
||||
int TRANSOBJ_TAG;
|
||||
};
|
||||
|
||||
#endif /* _CDEV_SIMPLE_REQUEST_OBJECT_H_ */
|
||||
+419
@@ -0,0 +1,419 @@
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with the construction of a service.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
// Revision History:
|
||||
// cdevSimpleService.cc,v
|
||||
// Revision 1.1 1996/11/21 18:22:24 akers
|
||||
// Non-Server Oriented Service
|
||||
//
|
||||
// Revision 1.1 1996/04/30 15:37:38 akers
|
||||
// Simple CDEV Service
|
||||
//
|
||||
// Revision 1.2 1996/03/21 13:57:55 akers
|
||||
// Major Modifications
|
||||
//
|
||||
// Revision 1.1.1.1 1996/02/28 16:36:21 akers
|
||||
// Initial release of support for ACE Services
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include <cdevSimpleService.h>
|
||||
#include <cdevSimpleRequestObject.h>
|
||||
#include <cdevClock.h>
|
||||
#include <ctype.h>
|
||||
|
||||
// *****************************************************************************
|
||||
// * defaultCallback:
|
||||
// * This static function is the default callback function that will be
|
||||
// * utilized for send and sendNoBlock.
|
||||
// *****************************************************************************
|
||||
static void defaultCallback(int, void *, cdevRequestObject &, cdevData &)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * trim :
|
||||
// * This method is used to remove any extraneous spaces from a message.
|
||||
// *****************************************************************************
|
||||
static char * trim ( char * ptr )
|
||||
{
|
||||
char * s1 = ptr;
|
||||
char * s2;
|
||||
|
||||
if(ptr!=NULL)
|
||||
{
|
||||
// *************************************************************
|
||||
// * Remove leading space from the string.
|
||||
// *************************************************************
|
||||
for(s1=ptr; isspace(*s1) && s1!=0; s1++);
|
||||
if(s1!=ptr) memmove(ptr, s1, strlen(s1)+1);
|
||||
|
||||
// *************************************************************
|
||||
// * Remove any multi-space entries from the string.
|
||||
// *************************************************************
|
||||
for(s1=ptr; *s1; s1++) if(isspace(*s1))
|
||||
{
|
||||
for(s2=s1; *s2 && isspace(*s2); s2++);
|
||||
if(s2>s1+1) memmove(s1+1, s2, strlen(s2)+1);
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * Remove trailing space from the string.
|
||||
// *************************************************************
|
||||
for(s1=&ptr[strlen(ptr)-1]; s1>=ptr && isspace(*s1); s1--) *s1=0;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::cdevSimpleService :
|
||||
// * This constructor is responsible for performing all service
|
||||
// * initialization.
|
||||
// *****************************************************************************
|
||||
cdevSimpleService::cdevSimpleService ( char * name, cdevSystem & system )
|
||||
: serviceFD(-1),
|
||||
queue(),
|
||||
selector(),
|
||||
callback(defaultCallback, NULL),
|
||||
cdevService(name, system)
|
||||
{
|
||||
// *********************************************************************
|
||||
// * Install the ACE_service specific flags
|
||||
// *********************************************************************
|
||||
installTags();
|
||||
|
||||
// *********************************************************************
|
||||
// * Clear local variables
|
||||
// *********************************************************************
|
||||
memset(&serviceFD, 0, sizeof(serviceFD));
|
||||
|
||||
// *********************************************************************
|
||||
// * Assign the value of the read file descriptor for the selector to
|
||||
// * the serviceFD variable.
|
||||
// *********************************************************************
|
||||
serviceFD = selector.readfd();
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::~cdevSimpleService :
|
||||
// * The destructor is protected to prevent it from being called directly.
|
||||
// * The destructor performs any clean-up or shutdown operations.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *****************************************************************************
|
||||
cdevSimpleService::~cdevSimpleService ( void )
|
||||
{
|
||||
// *********************************************************************
|
||||
// * Call flush to process all outbound messages.
|
||||
// *********************************************************************
|
||||
flush();
|
||||
|
||||
// *********************************************************************
|
||||
// * Clear the file descriptors used by cdev for polling.
|
||||
// *********************************************************************
|
||||
memset(&serviceFD, 0, sizeof(serviceFD));
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::installTags :
|
||||
// * Installs the tags that the service and service applications
|
||||
// * will use. This function is static to allow servers to setup
|
||||
// * the necessary tags without having to instanciate a cdevSimpleService object.
|
||||
// *****************************************************************************
|
||||
void cdevSimpleService::installTags ( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::getRequestObject :
|
||||
// * This is the interface that cdev objects will use to obtain a
|
||||
// * cdevSimpleRequestObject object. The cdevSimpleRequestObject
|
||||
// * represents a combined device and message pair that is associated
|
||||
// * with the cdevSimpleService.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int cdevSimpleService::getRequestObject ( char * device, char * message, cdevRequestObject * &req)
|
||||
{
|
||||
req = new cdevSimpleRequestObject (device, message, system_);
|
||||
return (req ? CDEV_SUCCESS : CDEV_ERROR);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::getFd
|
||||
// * This function will return the list of file descriptors that the
|
||||
// * cdevSimpleService is using. This will allow the file descriptors to be
|
||||
// * used in global select and poll calls performed at the cdevSystem class
|
||||
// * level.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleService::getFd ( int * &fd, int & numFd )
|
||||
{
|
||||
fd = &serviceFD;
|
||||
numFd = 1;
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::flush :
|
||||
// * This function flushes all communications buffers that the
|
||||
// * service may have open.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int cdevSimpleService::flush ( void )
|
||||
{
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::poll :
|
||||
// * This function polls the file descriptors used by the service
|
||||
// * until one of them becomes active or a discrete amount of time
|
||||
// * has expired.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleService::poll ( void )
|
||||
{
|
||||
return pend(0.0001);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::pend :
|
||||
// * Pends until the named file descriptor (or any file descriptor
|
||||
// * if fd = -1) is ready. Will pend forever if the descriptor does
|
||||
// * not become active.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleService::pend ( int )
|
||||
{
|
||||
while(!queue.empty()) handleOneEvent();
|
||||
|
||||
// *********************************************************************
|
||||
// * Empty the contents of the cdevSelector object.
|
||||
// *********************************************************************
|
||||
selector.purge();
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::pend :
|
||||
// * Pends until the named file descriptor (or any file descriptor
|
||||
// * if fd = -1) is ready. Will pend for no longer than the user
|
||||
// * specified number of seconds.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleService::pend ( double seconds, int )
|
||||
{
|
||||
cdevTimeValue sec = seconds;
|
||||
cdevClock timer;
|
||||
|
||||
timer.schedule(NULL, sec);
|
||||
|
||||
do {
|
||||
handleOneEvent();
|
||||
} while(!timer.expired() && !queue.empty());
|
||||
|
||||
// *********************************************************************
|
||||
// * Empty the contents of the cdevSelector object.
|
||||
// *********************************************************************
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::submit :
|
||||
// * This is the mechanism that the request object will use to submit a
|
||||
// * message to the service. It is important to note that all of the
|
||||
// * data provided to this object becomes the property of the service and
|
||||
// * must not be accessed afterwords.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleService::submit (cdevTranNode *node,
|
||||
char *device,
|
||||
char *message,
|
||||
cdevData *data)
|
||||
{
|
||||
cdevTransaction * transaction = new cdevTransaction;
|
||||
cdevServiceMessage * packet;
|
||||
|
||||
// *********************************************************************
|
||||
// * Populate the cdevTransaction structure with data.
|
||||
// *********************************************************************
|
||||
transaction->transnum = node->transaction();
|
||||
transaction->transobj = node;
|
||||
|
||||
// *********************************************************************
|
||||
// * Call trim on the device and message to remove any extra spaces.
|
||||
// *********************************************************************
|
||||
trim(device);
|
||||
trim(message);
|
||||
|
||||
// *********************************************************************
|
||||
// * Populate the packet variable with the data.
|
||||
// *********************************************************************
|
||||
|
||||
packet = new cdevServiceMessage(transaction, device, message, data);
|
||||
|
||||
// *********************************************************************
|
||||
// * Place the cdevServiceMessage into the queue.
|
||||
// *********************************************************************
|
||||
queue.enqueue(packet);
|
||||
|
||||
// *********************************************************************
|
||||
// * Add an event to the cdevSelector object in order to trigger polling
|
||||
// *********************************************************************
|
||||
selector.insertEvent();
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::dequeue :
|
||||
// * The handleOneEvent method uses this function to extract a single
|
||||
// * message from the service and process it. All data objects obtained
|
||||
// * through this function become the property of the caller and must
|
||||
// * be deleted.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleService::dequeue (cdevTransaction * &transaction,
|
||||
char * &device,
|
||||
char * &message,
|
||||
cdevData * &data)
|
||||
{
|
||||
int result = CDEV_ERROR;
|
||||
cdevServiceMessage * packet = (cdevServiceMessage *)queue.dequeue();
|
||||
|
||||
if(packet!=NULL)
|
||||
{
|
||||
transaction = packet->transaction;
|
||||
device = packet->device;
|
||||
message = packet->message;
|
||||
data = packet->data;
|
||||
result = CDEV_SUCCESS;
|
||||
delete packet;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::enqueue :
|
||||
// * The handleOneEvent method uses this function to dispatch callbacks
|
||||
// * after the function has been processed.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleService::enqueue (int status,
|
||||
cdevTransaction * trans,
|
||||
char * device,
|
||||
char * message,
|
||||
cdevData * data)
|
||||
{
|
||||
cdevTranNode * node = trans?trans->transobj:NULL;
|
||||
|
||||
if(node!=NULL && node->validate(trans->transnum)==CDEV_SUCCESS)
|
||||
{
|
||||
cdevData localData;
|
||||
|
||||
// *************************************************************
|
||||
// * cdevData must be returned to the caller.
|
||||
// *************************************************************
|
||||
if(node->resultData_==NULL) node->resultData_ = (data?data:&localData);
|
||||
else *(node->resultData_) = (data?*data:localData);
|
||||
|
||||
// *************************************************************
|
||||
// * Call the user provided callback function.
|
||||
// *************************************************************
|
||||
(node->userCallback_->callbackFunction())
|
||||
(status,
|
||||
node->userCallback_->userarg(),
|
||||
*node->reqObj_,
|
||||
*node->resultData_);
|
||||
|
||||
// *************************************************************
|
||||
// * Tag the transaction as finished
|
||||
// *************************************************************
|
||||
node->finished(1);
|
||||
|
||||
// *************************************************************
|
||||
// * Delete the cdevTranNode if it is not permanent.
|
||||
// *************************************************************
|
||||
if(!node->permanent()) delete node;
|
||||
|
||||
// *************************************************************
|
||||
// * Remove the event from the selector object.
|
||||
// *************************************************************
|
||||
selector.removeEvent();
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * Delete the components of the message.
|
||||
// *********************************************************************
|
||||
if(trans != NULL) delete trans;
|
||||
if(device != NULL) delete device;
|
||||
if(message != NULL) delete message;
|
||||
if(data != NULL) delete data;
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::handleOneEvent :
|
||||
// * This method allows the caller to handle individual events. This handler
|
||||
// * only processes one event and then returns to the caller.
|
||||
// *****************************************************************************
|
||||
void cdevSimpleService::handleOneEvent ( void )
|
||||
{
|
||||
cdevTransaction * transaction;
|
||||
char * device;
|
||||
char * message;
|
||||
cdevData * data;
|
||||
|
||||
if(dequeue(transaction, device, message, data)==CDEV_SUCCESS)
|
||||
{
|
||||
enqueue(CDEV_SUCCESS, transaction, device, message, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService::getNameServer :
|
||||
// * This function should obtain the default name server for this object.
|
||||
// * It does nothing for now.
|
||||
// *****************************************************************************
|
||||
int cdevSimpleService::getNameServer(cdevDevice * &ns)
|
||||
{
|
||||
ns = 0;
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
Executable
+229
@@ -0,0 +1,229 @@
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with the construction of a model service.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#if !defined (_CDEV_SIMPLE_SERVICE_H_)
|
||||
#define _CDEV_SIMPLE_SERVICE_H_
|
||||
|
||||
#include <cdevService.h>
|
||||
#include <cdevTranNode.h>
|
||||
#include <cdevSelector.h>
|
||||
#include <fifo.h>
|
||||
|
||||
// ****************************************************************************
|
||||
// * Service Loader:
|
||||
// * The first step in building a new service is to construct a service
|
||||
// * loader function. This function will allow cdev to dynamically
|
||||
// * initialize a service by name.
|
||||
// *
|
||||
// * The function should adhere to the following naming convention...
|
||||
// * cdevService * newXXX (char * name, cdevSystem * system);
|
||||
// *
|
||||
// * The 'XXX' should be replaced with the name of the service
|
||||
// * class.
|
||||
// *
|
||||
// * The function should also be declared as 'extern "C"' to allow it
|
||||
// * to be called and loaded from within an external shared library module.
|
||||
// *
|
||||
// * This function serves only to construct a new instance of the
|
||||
// * specified service, and return it to the instanciating mechanism.
|
||||
// *****************************************************************************
|
||||
// extern "C" cdevService *newcdevSimpleService ( char * name, cdevSystem * system );
|
||||
|
||||
// *****************************************************************************
|
||||
// * This structure is used to maintain a cdevTranNode class and its matching
|
||||
// * transaction number. The transaction number will be used to validate
|
||||
// * the cdevTranNode later.
|
||||
// *****************************************************************************
|
||||
typedef struct
|
||||
{
|
||||
int transnum;
|
||||
cdevTranNode * transobj;
|
||||
} cdevTransaction;
|
||||
|
||||
|
||||
// ******************************************************************************
|
||||
// * This is a structure that is used to store the components that are placed in
|
||||
// * the queues.
|
||||
// ******************************************************************************
|
||||
class cdevServiceMessage
|
||||
{
|
||||
public:
|
||||
cdevTransaction * transaction;
|
||||
char * device;
|
||||
char * message;
|
||||
cdevData * data;
|
||||
|
||||
cdevServiceMessage(cdevTransaction *Transaction=NULL,
|
||||
char *Device=NULL,
|
||||
char *Message=NULL,
|
||||
cdevData *Data=NULL)
|
||||
: transaction(Transaction),
|
||||
device(Device),
|
||||
message(Message),
|
||||
data(Data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevSimpleService:
|
||||
// * This is class provides the mechanisms that the cdev system will use
|
||||
// * to communicate with the model service.
|
||||
// *****************************************************************************
|
||||
class cdevSimpleService : public cdevService
|
||||
{
|
||||
friend class cdevSimpleRequestObject;
|
||||
|
||||
public:
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::cdevSimpleService :
|
||||
// * This constructor is responsible for performing all service
|
||||
// * initialization.
|
||||
// *********************************************************************
|
||||
cdevSimpleService ( char * name, cdevSystem & system );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::~cdevSimpleService :
|
||||
// * The destructor is protected to prevent it from being called
|
||||
// * directly. The destructor performs any clean-up or shutdown
|
||||
// * operations.
|
||||
// *
|
||||
// * Returns nothing.
|
||||
// *********************************************************************
|
||||
~cdevSimpleService ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::installTags :
|
||||
// * Installs the tags that the service and service applications
|
||||
// * will use. This function is static to allow servers to setup
|
||||
// * the necessary tags without having to instanciate a
|
||||
// * cdevSimpleService object.
|
||||
// *********************************************************************
|
||||
void installTags ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::getRequestObject :
|
||||
// * This is the interface that cdev objects will use to obtain a
|
||||
// * cdevSimpleRequestObject object. The cdevSimpleRequestObject
|
||||
// * represents a combined device and message pair that is associated
|
||||
// * with the cdevSimpleService.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int getRequestObject (char *, char *, cdevRequestObject * &);
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::getFd
|
||||
// * This function will return the list of file descriptors that the
|
||||
// * cdevSimpleService is using. This will allow the file
|
||||
// * descriptors to be used in global select and poll calls performed
|
||||
// * at the cdevSystem class level.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int getFd ( int * &fd, int & numFd );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::flush :
|
||||
// * This function flushes all communications buffers that the
|
||||
// * service may have open.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int flush ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::poll :
|
||||
// * This function polls the file descriptors used by the service
|
||||
// * until one of them becomes active or a discrete amount of time
|
||||
// * has expired.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int poll ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::pend :
|
||||
// * Pends until the named file descriptor (or any file descriptor
|
||||
// * if fd = -1) is ready. Will pend for no longer than the user
|
||||
// * specified number of seconds.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int pend ( double seconds, int = -1);
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::pend :
|
||||
// * Pends until the named file descriptor (or any file descriptor
|
||||
// * if fd = -1) is ready. Will pend forever if the descriptor does
|
||||
// * not become active.
|
||||
// *
|
||||
// * Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
|
||||
// *********************************************************************
|
||||
int pend ( int = -1);
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::submit :
|
||||
// * This is the mechanism that the request object will use to submit
|
||||
// * a message to the service. It is important to note that all of
|
||||
// * the data provided to this object becomes the property of the
|
||||
// * service and must not be accessed afterwords.
|
||||
// *********************************************************************
|
||||
virtual int submit (cdevTranNode *, char *, char *, cdevData *);
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::dequeue :
|
||||
// * The handleOneEvent method uses this function to extract a single
|
||||
// * message from the service and process it. All data objects
|
||||
// * obtained through this function become the property of the caller
|
||||
// * and must be deleted.
|
||||
// *********************************************************************
|
||||
virtual int dequeue (cdevTransaction * &, char * &, char * &, cdevData * &);
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::enqueue :
|
||||
// * The handleOneEvent method uses this function to dispatch
|
||||
// * callbacks after the function has been processed.
|
||||
// *********************************************************************
|
||||
virtual int enqueue (int, cdevTransaction *, char *, char *, cdevData *);
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::handleOneEvent :
|
||||
// * This method allows the caller to handle individual events. This
|
||||
// * handler only processes one event and then returns to the caller.
|
||||
// *********************************************************************
|
||||
virtual void handleOneEvent ( void );
|
||||
|
||||
// *********************************************************************
|
||||
// * cdevSimpleService::getNameServer :
|
||||
// * This function should obtain the default name server for this
|
||||
// * object. It does nothing for now.
|
||||
// *********************************************************************
|
||||
int getNameServer(cdevDevice * &ns);
|
||||
|
||||
|
||||
private:
|
||||
FifoQueue queue;
|
||||
int serviceFD;
|
||||
cdevSelector selector;
|
||||
cdevCallback callback;
|
||||
};
|
||||
|
||||
#endif /* _CDEV_SIMPLE_SERVICE_H_ */
|
||||
Executable
+145
@@ -0,0 +1,145 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with a cdevTranNode. The cdevTranNode is an extension
|
||||
// of the cdevTranObj. It provides a mechanism for tracking allocated
|
||||
// and unallocated cdevTranObj objects and prevents inadvertent writes
|
||||
// to unallocated memory.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
// Revision History:
|
||||
// cdevTranNode.cc,v
|
||||
// Revision 1.1 1996/11/21 18:22:27 akers
|
||||
// Non-Server Oriented Service
|
||||
//
|
||||
// Revision 1.1 1996/04/30 15:37:41 akers
|
||||
// Simple CDEV Service
|
||||
//
|
||||
// Revision 1.1.1.1 1996/02/28 16:36:20 akers
|
||||
// Initial release of support for ACE Services
|
||||
//
|
||||
// Revision 2.0 1995/10/04 19:21:37 withers
|
||||
// New CVS repository
|
||||
//
|
||||
// Revision 1.1.1.1 1995/10/04 18:45:08 bickley
|
||||
// CVS start of high-level apps
|
||||
//
|
||||
// Revision 1.1.1.1 1995/09/15 17:15:30 withers
|
||||
// MODEL SERVICE SOURCE
|
||||
//
|
||||
//
|
||||
#include <cdevTranNode.h>
|
||||
|
||||
// *****************************************************************************
|
||||
// * Static class members requiring initialization.
|
||||
// *****************************************************************************
|
||||
int cdevTranNode::count = 0;
|
||||
cdevTranNode * cdevTranNode::freeList = NULL;
|
||||
cdevTranNode * cdevTranNode::activeList = NULL;
|
||||
int cdevTranNode::initialized = 1;
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::new :
|
||||
// * This is the internal mechanism that is used to allocate new cdevTranNode
|
||||
// * objects. If an object is already available on the freelist, this
|
||||
// * function will allocate from that list to the activeList. Otherwise, a
|
||||
// * block of cdevTranNode objects will be allocated to repopulate the
|
||||
// * freeList first.
|
||||
// *****************************************************************************
|
||||
void * cdevTranNode::operator new ( size_t )
|
||||
{
|
||||
cdevTranNode * node;
|
||||
int i;
|
||||
|
||||
if(freeList==NULL)
|
||||
{
|
||||
freeList = ::new cdevTranNode[16];
|
||||
for(i=0; i<16; i++)
|
||||
{
|
||||
freeList[i].next = (i<15) ? &freeList[i+1] : NULL;
|
||||
freeList[i].allocated = FALSE;
|
||||
freeList[i].finished_ = FALSE;
|
||||
freeList[i].transaction_ = 0;
|
||||
}
|
||||
cdevTranNode::count-=16;
|
||||
}
|
||||
node = freeList;
|
||||
freeList = node->next;
|
||||
|
||||
node->allocated = TRUE;
|
||||
node->next = activeList;
|
||||
activeList = node;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::delete :
|
||||
// * This function is used to return an allocated cdevTranNode to the
|
||||
// * freeList for later allocation to another caller. This function will
|
||||
// * clear the transaction flag and will clear the allocated flag.
|
||||
// *****************************************************************************
|
||||
void cdevTranNode::operator delete ( void * ptr )
|
||||
{
|
||||
cdevTranNode * node = activeList;
|
||||
cdevTranNode * prev = NULL;
|
||||
|
||||
if(ptr != NULL)
|
||||
{
|
||||
while(node!=NULL && node!=(cdevTranNode *)ptr)
|
||||
{
|
||||
prev = node;
|
||||
node = prev->next;
|
||||
}
|
||||
if(node!=NULL)
|
||||
{
|
||||
if(prev) prev->next = node->next;
|
||||
else activeList = node->next;
|
||||
}
|
||||
|
||||
node = (cdevTranNode *)ptr;
|
||||
node->allocated = FALSE;
|
||||
node->finished_ = FALSE;
|
||||
node->transaction_ = 0;
|
||||
node->next = freeList;
|
||||
freeList = node;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::find:
|
||||
// * Allows the caller to locate a cdevTranNode using the transaction number.
|
||||
// *****************************************************************************
|
||||
cdevTranNode * cdevTranNode::find ( int Transaction )
|
||||
{
|
||||
cdevTranNode * node = activeList;
|
||||
while(node!=NULL && node->transaction_ != Transaction)
|
||||
{
|
||||
node = node->next;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::init:
|
||||
// * Allows the caller to initialize static members of the cdevTranNode class
|
||||
// *****************************************************************************
|
||||
void cdevTranNode::init ( void )
|
||||
{
|
||||
if(!initialized)
|
||||
{
|
||||
count = 0;
|
||||
freeList = NULL;
|
||||
activeList = NULL;
|
||||
initialized = 1;
|
||||
}
|
||||
}
|
||||
Executable
+165
@@ -0,0 +1,165 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// This header file contains the class definitions for the classes
|
||||
// associated with a cdevTranNode. The cdevTranNode is an extension
|
||||
// of the cdevTranObj. It provides a mechanism for tracking allocated
|
||||
// and unallocated cdevTranObj objects and prevents inadvertent writes
|
||||
// to unallocated memory.
|
||||
//
|
||||
// Author: Walt Akers
|
||||
//
|
||||
//
|
||||
//
|
||||
#ifndef _CDEV_TRAN_NODE_H_
|
||||
#define _CDEV_TRAN_NODE_H_
|
||||
|
||||
#include <cdevTranObj.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
class cdevTranNode : public cdevTranObj
|
||||
{
|
||||
private:
|
||||
static int count;
|
||||
static cdevTranNode * freeList;
|
||||
static cdevTranNode * activeList;
|
||||
static int initialized;
|
||||
|
||||
cdevTranNode * next;
|
||||
int allocated;
|
||||
|
||||
protected:
|
||||
int finished_;
|
||||
int permanent_;
|
||||
int transaction_;
|
||||
|
||||
public:
|
||||
cdevTranNode ( void );
|
||||
cdevTranNode ( cdevSystem*, cdevRequestObject*, cdevData*, cdevCallback*);
|
||||
~cdevTranNode( void );
|
||||
|
||||
void * operator new ( size_t size );
|
||||
void operator delete ( void * ptr );
|
||||
|
||||
int validate ( int Transaction );
|
||||
void transaction ( int Transaction );
|
||||
int transaction ( void );
|
||||
void finished ( int Finished );
|
||||
int finished ( void );
|
||||
void permanent ( int Permanent );
|
||||
int permanent ( void );
|
||||
|
||||
static cdevTranNode * find ( int Transaction );
|
||||
static void init ( void );
|
||||
};
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode :
|
||||
// * Allocates a cdevTranNode with no contents.
|
||||
// *****************************************************************************
|
||||
inline cdevTranNode::cdevTranNode ( void )
|
||||
: cdevTranObj(), finished_(FALSE), permanent_(FALSE)
|
||||
{
|
||||
if(!initialized) init();
|
||||
transaction_ = count++;
|
||||
disableDeleteCbk();
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode :
|
||||
// * Allocates a cdevTranNode populated with the required data values.
|
||||
// *****************************************************************************
|
||||
inline cdevTranNode::cdevTranNode ( cdevSystem * sys, cdevRequestObject *req,
|
||||
cdevData * data, cdevCallback * callback )
|
||||
: cdevTranObj(sys, req, data, callback), finished_(FALSE), permanent_(FALSE)
|
||||
{
|
||||
if(!initialized) init();
|
||||
transaction_ = count++;
|
||||
disableDeleteCbk();
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * ~cdevTranNode:
|
||||
// * Deletes the cdevTranNode object.
|
||||
// *****************************************************************************
|
||||
inline cdevTranNode::~cdevTranNode ( void )
|
||||
{
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::validate:
|
||||
// * Allows the user to verify that the cdevTranNode that he has a pointer
|
||||
// * to, corresponds to the specified Transaction number.
|
||||
// *****************************************************************************
|
||||
inline int cdevTranNode::validate ( int Transaction )
|
||||
{
|
||||
return (allocated==TRUE && transaction_==Transaction)?CDEV_SUCCESS:CDEV_NOTFOUND;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::transaction:
|
||||
// * Allows the caller to specify a new transaction number.
|
||||
// *****************************************************************************
|
||||
inline void cdevTranNode::transaction ( int Transaction )
|
||||
{
|
||||
transaction_ = Transaction;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::transaction:
|
||||
// * Allows the caller to obtain the transaction number.
|
||||
// *****************************************************************************
|
||||
inline int cdevTranNode::transaction ( void )
|
||||
{
|
||||
return transaction_;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::finished:
|
||||
// * Allows the caller to set the finished flag.
|
||||
// *****************************************************************************
|
||||
inline void cdevTranNode::finished ( int Finished )
|
||||
{
|
||||
finished_ = Finished?TRUE:FALSE;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::finished:
|
||||
// * Allows the caller to read the contents of the finished flag.
|
||||
// *****************************************************************************
|
||||
inline int cdevTranNode::finished ( void )
|
||||
{
|
||||
return finished_;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::permanent:
|
||||
// * Allows the caller to set the permanent flag.
|
||||
// *****************************************************************************
|
||||
inline void cdevTranNode::permanent ( int Permanent )
|
||||
{
|
||||
permanent_ = Permanent?TRUE:FALSE;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevTranNode::permanent:
|
||||
// * Allows the caller to read the contents of the permanent flag.
|
||||
// *****************************************************************************
|
||||
inline int cdevTranNode::permanent ( void )
|
||||
{
|
||||
return permanent_;
|
||||
}
|
||||
|
||||
#endif /* _CDEV_TRAN_NODE_H_ */
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
ARCH = hpux-sl
|
||||
include $(CDEV)/examples/Makefile.common
|
||||
|
||||
SRCROOT = $(CDEV)/extensions/cdevGenericServer
|
||||
CDEVSHOBJ = /usr/user4/mccops/lib/$(TARGETDIR)
|
||||
APPNAME = "CDEV Sample Service"
|
||||
|
||||
LIBDIR = $(CDEVLIB)
|
||||
INCDIR = $(SRCROOT)/include
|
||||
LIBS = -L$(LIBDIR) -lSimpleService \
|
||||
-L$(CDEVLIB) -lcdev \
|
||||
-ly -ll -L/lib -lm
|
||||
|
||||
LINKLIBS = -L$(LIBDIR) -lSimpleService\
|
||||
-ly -ll -L/lib -lm
|
||||
|
||||
CLASS_INCLUDES = -I./ -I$(INCDIR) -I$(CDEV)/extensions/SimpleService
|
||||
CXXEXTRA = -pta $(EPICSINCLUDES) $(ACE_INCLUDES) $(CLASS_INCLUDES)
|
||||
|
||||
SRCS = SampleService.cc
|
||||
|
||||
OBJS = SampleService.o
|
||||
|
||||
% : %.cc
|
||||
@rm -f $@
|
||||
@echo "=> $(CXX) $< -o $@"
|
||||
@$(CXX) $(CXXFLAGS) $(CXXEXTRA) $< -o $@ -L$(ACE_LIBDIR) $(ACE_LIBS)
|
||||
|
||||
ifeq ($(SHOBJ), YES)
|
||||
OUTPUTLIB = SampleService.so
|
||||
targets: buildingService $(CDEVSHOBJ)/$(CDEVVERSION)/SampleService.so
|
||||
|
||||
else
|
||||
OUTPUTLIB = libSampleService.a
|
||||
targets: buildingService $(CDEV)/lib/$(TARGETDIR)/libSampleService.a
|
||||
|
||||
endif
|
||||
|
||||
buildingService:
|
||||
@echo "BUILDING LIBRARY \"$(OUTPUTLIB)\"..."
|
||||
|
||||
objClean :
|
||||
@echo ""
|
||||
@echo "=> Removing old object files prior to building library"
|
||||
@rm -rf $(OBJS)
|
||||
|
||||
$(CDEVSHOBJ)/$(CDEVVERSION)/SampleService.so : $(OBJS) $(SRCS)
|
||||
@rm -f $@
|
||||
@echo "=> Building shared object $@"
|
||||
@echo " => Pleasuring templates for $@"
|
||||
@echo "int main() {return 0; }" >dummy.cc
|
||||
@$(CXX) $(CXXFLAGS) $(CXXEXTRA) dummy.cc $(SRCS) -Wl,+s -ptr./ptSampleService -ptr./ptrepository $(LIBS)
|
||||
@rm -rf a.out dummy.*
|
||||
@if test -f ./ptSampleService/*.o; \
|
||||
then \
|
||||
echo " => Linking $@ from objects and template objects"; \
|
||||
$(CXX) -b -o $@ $(OBJS) ptSampleService/*.o $(LINKLIBS); \
|
||||
else \
|
||||
echo " => Linking $@ from objects"; \
|
||||
$(CXX) -b -o $@ $(OBJS) $(LINKLIBS); \
|
||||
fi
|
||||
@echo " => $@ finished"
|
||||
|
||||
$(CDEV)/lib/$(TARGETDIR)/libSampleService.a : hail buildingService objClean $(OBJS)
|
||||
@rm -f $@
|
||||
@echo "=> Building archive library $@"
|
||||
@echo " => Linking $@ from objects"
|
||||
@ar ruv libSampleService.a $(OBJS)
|
||||
@chmod a+r libSampleService.a
|
||||
@echo " => $@ finished"
|
||||
|
||||
clean:
|
||||
@echo "=> Sample Service"
|
||||
@echo " => Removing old objects and binaries"
|
||||
@rm -rf $(OBJS) $(CDEVSHOBJ)/$(TARGETDIR)/SampleService.so a.out *.o *~ core ptrepository ptSampleService
|
||||
@echo " => Done"
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
service ca
|
||||
{
|
||||
tags {PV, READONLY}
|
||||
}
|
||||
|
||||
service Sample
|
||||
{
|
||||
tags {server}
|
||||
}
|
||||
|
||||
class BPM
|
||||
{
|
||||
verbs {get, set, monitorOn, monitorOff}
|
||||
attributes
|
||||
{
|
||||
attrib0 ca {PV = <>.VAL};
|
||||
attrib1 ca {PV = <>.VAL};
|
||||
attrib2 ca {PV = <>.VAL};
|
||||
attrib3 ca {PV = <>.VAL};
|
||||
attrib4 ca {PV = <>.VAL};
|
||||
attrib5 ca {PV = <>.VAL};
|
||||
attrib6 ca {PV = <>.VAL};
|
||||
attrib7 ca {PV = <>.VAL};
|
||||
attrib8 ca {PV = <>.VAL};
|
||||
attrib9 ca {PV = <>.VAL};
|
||||
}
|
||||
}
|
||||
|
||||
class Samples
|
||||
{
|
||||
verbs {get, set, monitorOn, monitorOff}
|
||||
attributes
|
||||
{
|
||||
default Sample;
|
||||
servers Sample;
|
||||
attrib0 Sample;
|
||||
attrib1 Sample;
|
||||
attrib2 Sample;
|
||||
attrib3 Sample;
|
||||
attrib4 Sample;
|
||||
attrib5 Sample;
|
||||
attrib6 Sample;
|
||||
attrib7 Sample;
|
||||
attrib8 Sample;
|
||||
attrib9 Sample;
|
||||
}
|
||||
messages
|
||||
{
|
||||
disconnect Sample;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BPM :
|
||||
IPM1S01, IPM1S02, IPM1S03, IPM1S05, IPM1S07,
|
||||
IPM1S08, IPM1S09
|
||||
;
|
||||
|
||||
Samples :
|
||||
device0, device1, device2, device3, device4,
|
||||
device5, device6, device7, device8, device9
|
||||
;
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#include "SampleService.h"
|
||||
|
||||
cdevService * newSampleService ( char * name, cdevSystem * system )
|
||||
{
|
||||
return new SampleService(name, *system);
|
||||
}
|
||||
|
||||
|
||||
SampleService::SampleService ( char * name, cdevSystem & system )
|
||||
: cdevSimpleService(name, system), var(0)
|
||||
{
|
||||
}
|
||||
|
||||
SampleService::~SampleService ( void )
|
||||
{
|
||||
}
|
||||
|
||||
void SampleService::handleOneEvent ( void )
|
||||
{
|
||||
cdevTransaction * transaction;
|
||||
char * device;
|
||||
char * message;
|
||||
cdevData * data;
|
||||
|
||||
if(dequeue(transaction, device, message, data)==CDEV_SUCCESS)
|
||||
{
|
||||
data->insert("device", device);
|
||||
data->insert("message", message);
|
||||
data->insert("value", var++);
|
||||
enqueue(CDEV_SUCCESS, transaction, device, message, data);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#include <cdevSimpleService.h>
|
||||
|
||||
extern "C" cdevService *newSampleService ( char * name, cdevSystem * system );
|
||||
|
||||
class SampleService : public cdevSimpleService
|
||||
{
|
||||
int var;
|
||||
|
||||
public:
|
||||
SampleService ( char * name, cdevSystem & system );
|
||||
virtual ~SampleService ( void );
|
||||
virtual void handleOneEvent( void );
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
=> @@echo = -o libSimpleService.sl;rm -rf /usr/local/i386-glibc22-linux/cdev-1.7.2/lib/Linux/libSimpleService.sl; mkdir -p /usr/local/i386-glibc22-linux/cdev-1.7.2/lib/Linux; g++ -shared libSimpleService.sl
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
ifneq ("$(VERBOSE)", "YES")
|
||||
MAKE := $(MAKE) -s VERBOSE=NO
|
||||
endif
|
||||
|
||||
BASEDIR = $(shell pwd)
|
||||
BASEINCLUDES = $(BASEDIR)/include
|
||||
BASEBIN = $(BASEDIR)/bin
|
||||
BASELIB = $(BASEDIR)/lib
|
||||
HEADERS = *.h *.i
|
||||
|
||||
SRCONLY_DIRS = $(BASEDIR)/cdevClient\
|
||||
$(BASEDIR)/cdevContextMap\
|
||||
$(BASEDIR)/cdevMonitorTable\
|
||||
$(BASEDIR)/cdevPacket\
|
||||
$(BASEDIR)/cdevServer\
|
||||
$(BASEDIR)/cdevTagMap\
|
||||
$(BASEDIR)/common\
|
||||
|
||||
LIB_DIRS = $(BASEDIR)/cdevReactor\
|
||||
$(BASEDIR)/NameServer/src\
|
||||
$(BASEDIR)/NameServer/cdev\
|
||||
$(BASEDIR)/lib
|
||||
|
||||
UTIL_DIRS = $(BASEDIR)/NameServer/dumpServer
|
||||
|
||||
EXAMPLE_DIRS = $(BASEDIR)/NameServer/examples\
|
||||
$(BASEDIR)/example
|
||||
|
||||
TEST_DIRS = $(BASEDIR)/tests\
|
||||
$(BASEDIR)/cdevReactor/TimerTest\
|
||||
$(BASEDIR)/cdevReactor/ServerTest
|
||||
|
||||
DOC_DIRS = $(BASEDIR)/doc\
|
||||
|
||||
HEADER_DIRS = $(BASEDIR)/cdevReactor\
|
||||
$(BASEDIR)/cdevTagMap\
|
||||
$(BASEDIR)/cdevContextMap\
|
||||
$(BASEDIR)/cdevMonitorTable\
|
||||
$(BASEDIR)/cdevPacket\
|
||||
$(BASEDIR)/common\
|
||||
$(BASEDIR)/cdevClient\
|
||||
$(BASEDIR)/cdevServer\
|
||||
$(BASEDIR)/NameServer/src\
|
||||
$(BASEDIR)/NameServer/cdev
|
||||
|
||||
CLEAN_DIRS = $(SRCONLY_DIRS)\
|
||||
$(LIB_DIRS)\
|
||||
$(UTIL_DIRS)\
|
||||
$(EXAMPLE_DIRS)\
|
||||
$(TEST_DIRS)\
|
||||
$(DOC_DIRS)
|
||||
|
||||
PURGE_DIRS = $(SRCONLY_DIRS)\
|
||||
$(BASEDIR)/cdevReactor\
|
||||
$(BASEDIR)/NameServer/src\
|
||||
$(BASEDIR)/NameServer/cdev\
|
||||
$(BASEDIR)/liteClient\
|
||||
$(UTIL_DIRS)\
|
||||
$(EXAMPLE_DIRS)\
|
||||
$(TEST_DIRS)\
|
||||
$(DOC_DIRS)
|
||||
|
||||
all: directories headers archive shared utils
|
||||
|
||||
directories:
|
||||
@echo "=> Creating directories for binary files"
|
||||
@mkdir -p $(BASEBIN)
|
||||
@mkdir -p $(BASELIB)
|
||||
@echo "<= Done...\n"
|
||||
|
||||
headers:
|
||||
@echo "=> Linking header files to include directory"
|
||||
@for dir in $(HEADER_DIRS); \
|
||||
do \
|
||||
cd $$dir; \
|
||||
for file in $(HEADERS); \
|
||||
do \
|
||||
if test -f $$file; then cp $$dir/$$file $(BASEINCLUDES)/$$file; fi; \
|
||||
done \
|
||||
done
|
||||
@cp $(BASEDIR)/include/makeinclude/Makefile.lib $(BASEDIR)/lib/Makefile
|
||||
@echo "<= Done...\n"
|
||||
|
||||
archive:
|
||||
@echo "=> Building archive version of libraries"
|
||||
@for dir in $(LIB_DIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir SHOBJ=NO; \
|
||||
done
|
||||
@echo "<= Done...\n"
|
||||
|
||||
shared:
|
||||
@echo "=> Building shared version of libraries"
|
||||
@for dir in $(LIB_DIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir SHOBJ=YES; \
|
||||
done
|
||||
@echo "<= Done...\n"
|
||||
|
||||
utils:
|
||||
@echo "=> Building utility programs"
|
||||
@for dir in $(UTIL_DIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir SHOBJ=YES; \
|
||||
done
|
||||
@echo "<= Done...\n"
|
||||
|
||||
examples:
|
||||
@echo "=> Building example programs"
|
||||
@for dir in $(EXAMPLE_DIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir SHOBJ=YES; \
|
||||
done
|
||||
@echo "<= Done...\n"
|
||||
|
||||
apps:
|
||||
@echo "=> Building test programs"
|
||||
@for dir in $(TEST_DIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir SHOBJ=YES; \
|
||||
done
|
||||
@echo "<= Done...\n"
|
||||
|
||||
clean:
|
||||
@echo "=> Cleaning CDEV Generic Server Directories"
|
||||
@for dir in $(CLEAN_DIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir clean; \
|
||||
done
|
||||
@echo "<= Done...\n"
|
||||
|
||||
purge:
|
||||
@echo "=> Purging CDEV Generic Server Directories"
|
||||
@echo " => Removing links to header files"
|
||||
@rm -rf $(BASEINCLUDES)/*.h $(BASEINCLUDES)/*.i
|
||||
@echo " Done..."
|
||||
@for dir in $(PURGE_DIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir purge; \
|
||||
done
|
||||
@rm -rf $(BASEDIR)/lib
|
||||
@rm -rf $(BASEDIR)/bin
|
||||
@echo "<= Done...\n"
|
||||
@@ -0,0 +1,135 @@
|
||||
!IF "$(VERBOSE)" != "YES"
|
||||
MAKE = $(MAKE) -s VERBOSE=NO
|
||||
!ENDIF
|
||||
|
||||
BASEDIR = $(MAKEDIR)
|
||||
BASEINCLUDES = $(BASEDIR)\include
|
||||
BASEBIN = $(BASEDIR)\bin
|
||||
BASELIB = $(BASEDIR)\lib
|
||||
HEADERS = dir\*.h dir\*.i
|
||||
|
||||
SRCONLY_DIRS = $(BASEDIR)\cdevClient\
|
||||
$(BASEDIR)\cdevContextMap\
|
||||
$(BASEDIR)\cdevMonitorTable\
|
||||
$(BASEDIR)\cdevPacket\
|
||||
$(BASEDIR)\cdevServer\
|
||||
$(BASEDIR)\cdevTagMap\
|
||||
$(BASEDIR)\common\
|
||||
|
||||
LIB_DIRS = $(BASEDIR)\cdevReactor\
|
||||
$(BASEDIR)\NameServer\src\
|
||||
$(BASEDIR)\NameServer\cdev\
|
||||
$(BASEDIR)\lib\
|
||||
$(BASEDIR)\liteClient
|
||||
|
||||
UTIL_DIRS = $(BASEDIR)\NameServer\dumpServer
|
||||
|
||||
EXAMPLE_DIRS = $(BASEDIR)\NameServer\examples\
|
||||
$(BASEDIR)\example
|
||||
|
||||
TEST_DIRS = $(BASEDIR)\tests\
|
||||
$(BASEDIR)\cdevReactor\TimerTest\
|
||||
$(BASEDIR)\cdevReactor\ServerTest
|
||||
|
||||
DOC_DIRS = $(BASEDIR)\doc\
|
||||
|
||||
HEADER_DIRS = $(BASEDIR)\cdevReactor\
|
||||
$(BASEDIR)\cdevTagMap\
|
||||
$(BASEDIR)\cdevContextMap\
|
||||
$(BASEDIR)\cdevMonitorTable\
|
||||
$(BASEDIR)\cdevPacket\
|
||||
$(BASEDIR)\common\
|
||||
$(BASEDIR)\cdevClient\
|
||||
$(BASEDIR)\cdevServer\
|
||||
$(BASEDIR)\NameServer\src\
|
||||
$(BASEDIR)\NameServer\cdev
|
||||
|
||||
CLEAN_DIRS = $(SRCONLY_DIRS)\
|
||||
$(LIB_DIRS)\
|
||||
$(UTIL_DIRS)\
|
||||
$(EXAMPLE_DIRS)\
|
||||
$(TEST_DIRS)\
|
||||
$(DOC_DIRS)
|
||||
|
||||
all: hail directories headers shared utils fairwell
|
||||
|
||||
everything: hail directories headers shared utils examples apps other fairwell
|
||||
|
||||
hail:
|
||||
@echo ---------------------------------------------------------------
|
||||
@echo Building CDEV Generic Server for Target : $(ARCH)
|
||||
@echo ---------------------------------------------------------------
|
||||
|
||||
fairwell:
|
||||
@echo ---------------------------------------------------------------
|
||||
@echo CDEV Generic Server has been built for Target : $(ARCH)
|
||||
@echo ---------------------------------------------------------------
|
||||
|
||||
directories:
|
||||
@echo =^> Creating directories for binary files
|
||||
-@if not exist $(BASEBIN) mkdir $(BASEBIN)
|
||||
-@if not exist $(BASELIB) mkdir $(BASELIB)
|
||||
-@copy $(BASEINCLUDES)\makeinclude\NMakefile.lib $(BASELIB)\NMakefile.mak
|
||||
@echo ^<= Done...
|
||||
|
||||
headers:
|
||||
@echo =^> Copying header files to include directory
|
||||
-@for %d in ($(HEADER_DIRS)) do @for %f in ($(HEADERS:dir=%d)) do @copy %f $(BASEINCLUDES) > nul
|
||||
@echo ^<= Done...
|
||||
|
||||
archives:
|
||||
@echo =^> Building archive version of libraries
|
||||
@for %d in ($(LIB_DIRS)) do @cd %d & $(MAKE) /NOLOGO SHOBJ=NO /f NMakefile.mak
|
||||
@echo <^= Done...
|
||||
|
||||
shared:
|
||||
@echo =^> Building shared version of libraries
|
||||
@for %d in ($(LIB_DIRS)) do @cd %d & $(MAKE) /NOLOGO SHOBJ=YES /f NMakefile.mak
|
||||
@echo ^<= Done...
|
||||
|
||||
utils:
|
||||
@echo =^> Building utility programs
|
||||
@for %d in ($(UTIL_DIRS)) do @cd %d & $(MAKE) /NOLOGO SHOBJ=YES /f NMakefile.mak
|
||||
@echo ^<= Done...
|
||||
|
||||
examples:
|
||||
@echo =^> Building example programs
|
||||
@for %d in ($(EXAMPLE_DIRS)) do @cd %d & $(MAKE) /NOLOGO SHOBJ=YES /f NMakefile.mak
|
||||
@echo ^<= Done...
|
||||
|
||||
apps:
|
||||
@echo =^> Building test programs
|
||||
@for %d in ($(TEST_DIRS)) do @cd %d & $(MAKE) /NOLOGO SHOBJ=YES /f NMakefile.mak
|
||||
@echo ^<= Done...
|
||||
|
||||
other:
|
||||
@echo =^> Building miscellaneous applications and libraries
|
||||
@for %d in ($(SRCONLY_DIRS)) do @cd %d & $(MAKE) /NOLOGO SHOBJ=YES /f NMakefile.mak
|
||||
@echo ^<= Done...
|
||||
|
||||
clean:
|
||||
@echo =^> Cleaning CDEV Generic Server Directories
|
||||
@for %d in ($(CLEAN_DIRS)) do @if exist %d\NMakefile.mak cd %d & $(MAKE) /NOLOGO /f NMakefile.mak clean
|
||||
@echo ^<= Done...
|
||||
|
||||
purge:
|
||||
@echo =^> Purging CDEV Generic Server Directories
|
||||
@echo ^ ^ ^ =^> Removing header files
|
||||
-@for %f in ($(BASEINCLUDES)\*.h $(BASEINCLUDES)\*.i) do @erase %f
|
||||
@echo ^ ^ ^ ^ ^ ^ Done...
|
||||
@for %d in ($(CLEAN_DIRS)) do @if exist %d\NMakefile.mak cd %d & $(MAKE) /NOLOGO /f NMakefile.mak purge
|
||||
-@if exist $(BASEDIR)\lib rmdir /s /q $(BASEDIR)\lib
|
||||
-@if exist $(BASEDIR)\bin rmdir /s /q $(BASEDIR)\bin
|
||||
@echo ^<= Done...
|
||||
|
||||
!IF "$(SUBTARGETDIR)" == ""
|
||||
subtarget :
|
||||
-@echo SUBTARGETDIR variable must be defined to build subtargets
|
||||
!ELSE
|
||||
!IF "$(SUBTARGET)" == ""
|
||||
SUBTARGET = all
|
||||
!ENDIF
|
||||
subtarget :
|
||||
@cd $(SUBTARGETDIR)
|
||||
@$(MAKE) /NOLOGO /f NMakefile.mak $(SUBTARGET)
|
||||
!ENDIF
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
BASEDIR = $(shell pwd)
|
||||
BUILDDIRS = $(BASEDIR)/src $(BASEDIR)/cdev $(BASEDIR)/dumpServer $(BASEDIR)/examples
|
||||
CLEANDIRS = $(BASEDIR)/src $(BASEDIR)/cdev $(BASEDIR)/dumpServer $(BASEDIR)/examples
|
||||
|
||||
all:
|
||||
@for dir in $(BUILDDIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir; \
|
||||
done
|
||||
|
||||
clean:
|
||||
@for dir in $(CLEANDIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir clean; \
|
||||
done
|
||||
|
||||
purge:
|
||||
@for dir in $(CLEANDIRS); \
|
||||
do \
|
||||
$(MAKE) -C $$dir purge; \
|
||||
done
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+83
@@ -0,0 +1,83 @@
|
||||
ARCH = OS
|
||||
SHOBJ = YES
|
||||
APPNAME = "Name Server Interface for CDEV"
|
||||
|
||||
include ../../include/makeinclude/Makefile.$(ARCH)
|
||||
|
||||
TEMPLINKS = rsvcSlist.cc \
|
||||
rsvcHSlist.cc \
|
||||
rsvcHash.cc \
|
||||
rsvcDataStreamer.cc \
|
||||
rsvcDataEntry.cc \
|
||||
rsvcData.cc \
|
||||
rsvcNetData.cc \
|
||||
rsvcCbk.cc \
|
||||
rsvcHashable.cc \
|
||||
rsvcStreamable.cc \
|
||||
rsvcCallback.cc \
|
||||
rsvcClient.cc \
|
||||
rsvcUdpClient.cc
|
||||
OBJS = $(OBJDIR)/rsvcSlist.o \
|
||||
$(OBJDIR)/rsvcHSlist.o \
|
||||
$(OBJDIR)/rsvcHash.o \
|
||||
$(OBJDIR)/rsvcDataStreamer.o \
|
||||
$(OBJDIR)/rsvcDataEntry.o \
|
||||
$(OBJDIR)/rsvcData.o \
|
||||
$(OBJDIR)/rsvcNetData.o \
|
||||
$(OBJDIR)/rsvcCbk.o \
|
||||
$(OBJDIR)/rsvcHashable.o \
|
||||
$(OBJDIR)/rsvcStreamable.o \
|
||||
$(OBJDIR)/rsvcCallback.o \
|
||||
$(OBJDIR)/rsvcClient.o \
|
||||
$(OBJDIR)/rsvcUdpClient.o \
|
||||
$(OBJDIR)/rnsService.o \
|
||||
$(OBJDIR)/rnsRequestObject.o
|
||||
|
||||
ifeq ($(SHOBJ),YES)
|
||||
TARGETS = $(CDEVSHOBJ)/$(CDEVVERSION)/rnsService.so $(BASEBIN)/cdev_test
|
||||
else
|
||||
TARGETS = $(BASELIB)/librnsService.a
|
||||
endif
|
||||
|
||||
CXXINCLUDES = -I./
|
||||
LIBS = -L$(CDEVLIB) -lcdevReactor $(CDEVLIBS) $(OSLIBS)
|
||||
BINARIES = $(BASEBIN)/cdev_test $(BASELIB)/rnsService.so $(BASELIB)/librnsService.a $(TEMPLINKS)
|
||||
|
||||
targets: $(TEMPLINKS) $(TARGETS)
|
||||
|
||||
$(TEMPLINKS) :
|
||||
@cp $^ $@
|
||||
|
||||
$(BASEBIN)/cdev_test: $(OBJDIR)/cdev_test.o
|
||||
$(LINK.cc) $^ $(LIBS) -o $@
|
||||
|
||||
$(BASELIB)/librnsService.a: $(OBJS)
|
||||
$(LINK.a) $@ $^
|
||||
@$(RANLIB) $@ > /dev/null
|
||||
@cp $@ $(CDEVLIB)
|
||||
|
||||
$(BASELIB)/rnsService.so: $(OBJS)
|
||||
@mkdir -p $(CDEVSHOBJ)/$(CDEVVERSION)
|
||||
$(LINK.so) -o $@ $^ $(NETLIBS)
|
||||
@cp $@ $(CDEVSHOBJ)/$(CDEVVERSION)
|
||||
|
||||
|
||||
$(CDEVSHOBJ)/$(CDEVVERSION)/rnsService.so : $(BASELIB)/rnsService.so
|
||||
@mkdir -p $(@D)
|
||||
@echo " => Copying $(@^) to $@"
|
||||
@rm -f $@
|
||||
@cp $^ $@
|
||||
|
||||
rsvcSlist.cc : ../src/rsvcSlist.cc
|
||||
rsvcHSlist.cc : ../src/rsvcHSlist.cc
|
||||
rsvcHash.cc : ../src/rsvcHash.cc
|
||||
rsvcDataStreamer.cc : ../src/rsvcDataStreamer.cc
|
||||
rsvcDataEntry.cc : ../src/rsvcDataEntry.cc
|
||||
rsvcData.cc : ../src/rsvcData.cc
|
||||
rsvcNetData.cc : ../src/rsvcNetData.cc
|
||||
rsvcCbk.cc : ../src/rsvcCbk.cc
|
||||
rsvcHashable.cc : ../src/rsvcHashable.cc
|
||||
rsvcStreamable.cc : ../src/rsvcStreamable.cc
|
||||
rsvcCallback.cc : ../src/rsvcCallback.cc
|
||||
rsvcClient.cc : ../src/rsvcClient.cc
|
||||
rsvcUdpClient.cc : ../src/rsvcUdpClient.cc
|
||||
@@ -0,0 +1,118 @@
|
||||
.SUFFIXES: .cc .obj
|
||||
|
||||
APPNAME = Name Server Interface for CDEV
|
||||
ARCH = WINNT-4.0
|
||||
|
||||
BINARIES = $(TEMPLINKS) $(BASEBIN)\cdev_test
|
||||
|
||||
include ..\..\include\makeinclude\Makefile.WINNT-4.0
|
||||
|
||||
TEMPLINKS = rsvcSlist.cc\
|
||||
rsvcHSlist.cc\
|
||||
rsvcHash.cc\
|
||||
rsvcDataStreamer.cc\
|
||||
rsvcDataEntry.cc\
|
||||
rsvcData.cc\
|
||||
rsvcNetData.cc\
|
||||
rsvcCbk.cc\
|
||||
rsvcHashable.cc\
|
||||
rsvcStreamable.cc\
|
||||
rsvcCallback.cc\
|
||||
rsvcClient.cc\
|
||||
rsvcUdpClient.cc
|
||||
OBJS = $(OBJDIR)\rsvcSlist.obj\
|
||||
$(OBJDIR)\rsvcHSlist.obj\
|
||||
$(OBJDIR)\rsvcHash.obj\
|
||||
$(OBJDIR)\rsvcDataStreamer.obj\
|
||||
$(OBJDIR)\rsvcDataEntry.obj\
|
||||
$(OBJDIR)\rsvcData.obj\
|
||||
$(OBJDIR)\rsvcNetData.obj\
|
||||
$(OBJDIR)\rsvcCbk.obj\
|
||||
$(OBJDIR)\rsvcHashable.obj\
|
||||
$(OBJDIR)\rsvcStreamable.obj\
|
||||
$(OBJDIR)\rsvcCallback.obj\
|
||||
$(OBJDIR)\rsvcClient.obj\
|
||||
$(OBJDIR)\rsvcUdpClient.obj\
|
||||
$(OBJDIR)\rnsService.obj\
|
||||
$(OBJDIR)\rnsRequestObject.obj
|
||||
|
||||
!IF "$(SHOBJ)" == "YES"
|
||||
TARGETS = $(TEMPLINKS) $(CDEVSHOBJ)\$(CDEVVERSION)\rnsService.dll $(BASEBIN)\cdev_test.exe
|
||||
!ELSE
|
||||
TARGETS = $(TEMPLINKS) $(CDEVLIB)\rnsService.lib
|
||||
!ENDIF
|
||||
|
||||
CXXINCLUDES = -I.\\
|
||||
CXXEXTRA_DLL = /D "_RSVC_CORE_EXPORTS_=1"
|
||||
|
||||
targets : $(TARGETS)
|
||||
@erase $(TEMPLINKS)
|
||||
|
||||
$(BASEBIN)\cdev_test.exe: $(OBJDIR)\cdev_test.obj
|
||||
-@if exist $@ erase $@
|
||||
@echo ^ ^ ^ ^ ^ ^ =^> Linking $(@F)
|
||||
$(LINK) $(CDEVLIB)\cdev.lib\
|
||||
$(LINK_EXE_FLAGS) /out:$@ $?
|
||||
@echo ^ ^ ^ ^ ^ ^ ^ ^ ^ Done...
|
||||
|
||||
$(CDEVLIB)\rnsService.lib: $(OBJS)
|
||||
@echo ^ ^ ^ =^> Linking $(@F)
|
||||
-@if exist $@ erase $@
|
||||
-@if not exist $(@D) mkdir $(@D)
|
||||
@$(LIB32) $(CDEVLIB)\cdev.lib\
|
||||
$(LINK_LIB_FLAGS) /out:$@ $(OBJS)
|
||||
@echo ^ ^ ^ ^ ^ ^ Done...
|
||||
|
||||
$(CDEVLIB)\rnsService.dll: $(OBJS)
|
||||
@echo ^ ^ ^ =^> Linking $(@F)
|
||||
-@if exist $@ erase $@
|
||||
-@if not exist $(@D) mkdir $(@D)
|
||||
@$(LIB32) $(CDEVLIB)\cdev.lib\
|
||||
$(LINK_DLL_FLAGS) /out:$@ /implib:$(@D)\$(@B).lib $(OBJS)
|
||||
-@if not exist $(CDEVSHOBJ)\$(CDEVVERSION) mkdir $(CDEVSHOBJ)\$(CDEVVERSION)
|
||||
@copy $@ $(CDEVSHOBJ)\$(CDEVVERSION)\$(@F) > nul
|
||||
@echo ^ ^ ^ ^ ^ ^ Done...
|
||||
|
||||
$(CDEVSHOBJ)\$(CDEVVERSION)\rnsService.dll : $(CDEVLIB)\rnsService.dll
|
||||
@echo ^ ^ ^ =^> Transfer $(@F) to CDEVSHOBJ directory
|
||||
-@copy $(CDEVLIB)\rnsService.dll $@
|
||||
|
||||
rsvcSlist.cc : ..\src\rsvcSlist.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcHSlist.cc : ..\src\rsvcHSlist.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcHash.cc : ..\src\rsvcHash.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcDataStreamer.cc : ..\src\rsvcDataStreamer.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcDataEntry.cc : ..\src\rsvcDataEntry.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcData.cc : ..\src\rsvcData.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcNetData.cc : ..\src\rsvcNetData.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcCbk.cc : ..\src\rsvcCbk.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcHashable.cc : ..\src\rsvcHashable.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcStreamable.cc : ..\src\rsvcStreamable.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcCallback.cc : ..\src\rsvcCallback.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcClient.cc : ..\src\rsvcClient.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
rsvcUdpClient.cc : ..\src\rsvcUdpClient.cc
|
||||
-@$(CREATE_LINK)
|
||||
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
// simple test for name server cdev interface
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <cdevSystem.h>
|
||||
#include <cdevRequestObject.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
inline int strcasecmp ( const char * string1, const char * string2 )
|
||||
{
|
||||
return _stricmp(string1, string2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void entryCallback (int status, void *,
|
||||
cdevRequestObject&, cdevData& data)
|
||||
{
|
||||
if (status == CDEV_SUCCESS || status == CDEV_INCOMPLETE) {
|
||||
printf ("New server is here \n");
|
||||
data.asciiDump ();
|
||||
}
|
||||
else if (status == CDEV_CBK_FINISHED) {
|
||||
printf ("entry monitor finished\n");
|
||||
}
|
||||
else if (status == CDEV_DISCONNECTED)
|
||||
printf ("Server is gone\n");
|
||||
else
|
||||
printf ("monitor callback failed\n");
|
||||
}
|
||||
|
||||
static void monCallback (int status, void* /* arg */,
|
||||
cdevRequestObject& /* obj */, cdevData& data)
|
||||
{
|
||||
if (status == CDEV_SUCCESS)
|
||||
data.asciiDump ();
|
||||
else if (status == CDEV_CBK_FINISHED) {
|
||||
printf ("monitor finished\n");
|
||||
data.asciiDump ();
|
||||
}
|
||||
else if (status == CDEV_DISCONNECTED)
|
||||
printf ("server is dead\n");
|
||||
else
|
||||
printf ("monitor callback failed\n");
|
||||
}
|
||||
|
||||
int main (int /* argc */, char** /* argv */)
|
||||
{
|
||||
cdevSystem& system = cdevSystem::defaultSystem ();
|
||||
char temp[100];
|
||||
char comd[100];
|
||||
|
||||
printf ("Enter cdev test command\n");
|
||||
scanf ("%s", comd);
|
||||
|
||||
if (strcasecmp (comd, "get") == 0) {
|
||||
cdevRequestObject* obj = cdevRequestObject::attachPtr ("serverNs", "get");
|
||||
|
||||
if (obj) {
|
||||
cdevData result;
|
||||
cdevData out;
|
||||
printf ("enter namd and domain \n");
|
||||
char name[100], domain[100];
|
||||
scanf ("%s %s", name, domain);
|
||||
out.insert ("name", name);
|
||||
out.insert ("domain", domain);
|
||||
|
||||
if (obj->send (out, result) == CDEV_SUCCESS) {
|
||||
result.asciiDump ();
|
||||
}
|
||||
else
|
||||
printf ("get data failed\n");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp (comd, "monitorOn") == 0) {
|
||||
cdevRequestObject* obj = cdevRequestObject::attachPtr ("serverNs",
|
||||
"monitorOn");
|
||||
if (obj) {
|
||||
cdevData result;
|
||||
cdevData out;
|
||||
printf ("enter namd and domain \n");
|
||||
char name[100], domain[100];
|
||||
scanf ("%s %s", name, domain);
|
||||
|
||||
out.insert ("name", name);
|
||||
out.insert ("domain", domain);
|
||||
|
||||
cdevCallback cbk (monCallback, 0);
|
||||
|
||||
if (obj->sendCallback (out, cbk) != CDEV_SUCCESS)
|
||||
printf ("monitor data failed\n");
|
||||
else {
|
||||
while (1)
|
||||
system.pend ();
|
||||
}
|
||||
|
||||
// now remove monitor
|
||||
cdevRequestObject* obj0 = cdevRequestObject::attachPtr ("serverNs",
|
||||
"monitorOff");
|
||||
if (obj0) {
|
||||
if (obj0->sendCallback (out, cbk) != CDEV_SUCCESS)
|
||||
printf ("monitor off data failed\n");
|
||||
else
|
||||
system.pend (20.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp (comd, "monitorEntry") == 0) {
|
||||
cdevRequestObject* obj = cdevRequestObject::attachPtr ("serverNs",
|
||||
"monitorEntry");
|
||||
if (obj) {
|
||||
cdevCallback cbk (entryCallback, 0);
|
||||
|
||||
if (obj->sendCallback (0, cbk) != CDEV_SUCCESS)
|
||||
printf ("monitor entry failed\n");
|
||||
else {
|
||||
while (1)
|
||||
system.pend ();
|
||||
}
|
||||
|
||||
// now remove monitor
|
||||
cdevRequestObject* obj0 = cdevRequestObject::attachPtr ("serverNs",
|
||||
"monitorEntryOff");
|
||||
if (obj0) {
|
||||
if (obj0->sendCallback (0, cbk) != CDEV_SUCCESS)
|
||||
printf ("monitor off data failed\n");
|
||||
else
|
||||
system.pend (20.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
service rns {
|
||||
tags {PV}
|
||||
}
|
||||
|
||||
class RNS {
|
||||
messages {
|
||||
get rns;
|
||||
monitorOn rns;
|
||||
monitorOff rns;
|
||||
monitorEntry rns;
|
||||
monitorEntryOff rns;
|
||||
}
|
||||
}
|
||||
|
||||
RNS :
|
||||
serverNs
|
||||
;
|
||||
@@ -0,0 +1,54 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// Name Server Monitor Object
|
||||
//
|
||||
// Author: Jie Chen
|
||||
//
|
||||
//
|
||||
//
|
||||
#ifndef _RNS_MONITOR_OBJ_H
|
||||
#define _RNS_MONITOR_OBJ_H
|
||||
|
||||
#include <cdevMonitorObj.h>
|
||||
|
||||
class rnsRequestObject;
|
||||
|
||||
class rnsMonitorObj : public cdevMonitorObj
|
||||
{
|
||||
public:
|
||||
// constructor and destructor
|
||||
rnsMonitorObj (cdevTranObj& tranObj)
|
||||
:cdevMonitorObj (tranObj), out_ (0), started_ (1)
|
||||
{
|
||||
#ifdef _TRACE_OBJECTS
|
||||
printf (" Create rnsMonitorObj Class Object\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
~rnsMonitorObj (void)
|
||||
{
|
||||
#ifdef _TRACE_OBJECTS
|
||||
printf (" Delete rnsMonitorObj Class Object\n");
|
||||
#endif
|
||||
if (out_)
|
||||
delete out_;
|
||||
}
|
||||
|
||||
const char* className (void) const {return "rnsMonitorObj";}
|
||||
|
||||
// out bound cdevdata
|
||||
cdevData* out_;
|
||||
|
||||
// whether this monitor callback is restarted or not
|
||||
int started_;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,439 @@
|
||||
#include <cdevSystem.h>
|
||||
#include <cdevRequestObject.h>
|
||||
#include <cdevData.h>
|
||||
#include <cdevCallback.h>
|
||||
|
||||
class rnsQueryCollector
|
||||
{
|
||||
private:
|
||||
cdevData * data;
|
||||
int deleteFlag;
|
||||
unsigned char * byteData;
|
||||
short * shortData;
|
||||
unsigned short * ushortData;
|
||||
long * longData;
|
||||
unsigned long * ulongData;
|
||||
float * floatData;
|
||||
double * doubleData;
|
||||
cdev_TS_STAMP * tsData;
|
||||
size_t byteCnt;
|
||||
size_t shortCnt;
|
||||
size_t ushortCnt;
|
||||
size_t longCnt;
|
||||
size_t ulongCnt;
|
||||
size_t floatCnt;
|
||||
size_t doubleCnt;
|
||||
size_t tsCnt;
|
||||
|
||||
public:
|
||||
rnsQueryCollector ( cdevData & userData, int deleteData = 0 )
|
||||
: data(&userData), deleteFlag(deleteData),
|
||||
byteData(NULL), shortData(NULL), ushortData(NULL),
|
||||
longData(NULL), ulongData(NULL), floatData(NULL),
|
||||
doubleData(NULL), tsData(NULL), byteCnt(0),
|
||||
shortCnt(0), ushortCnt(0), longCnt(0), ulongCnt(0),
|
||||
floatCnt(0), doubleCnt(0), tsCnt(0)
|
||||
{
|
||||
data->remove();
|
||||
}
|
||||
|
||||
~rnsQueryCollector ( void )
|
||||
{
|
||||
if(deleteFlag) delete data;
|
||||
if(byteData) delete byteData;
|
||||
if(shortData) delete shortData;
|
||||
if(ushortData) delete ushortData;
|
||||
if(longData) delete longData;
|
||||
if(ulongData) delete ulongData;
|
||||
if(floatData) delete floatData;
|
||||
if(doubleData) delete doubleData;
|
||||
if(tsData) delete tsData;
|
||||
}
|
||||
|
||||
cdevData * getData ( void ) { return data; }
|
||||
void clearData ( void ) { data->remove(); }
|
||||
inline int collect ( cdevData & userData );
|
||||
|
||||
private:
|
||||
inline int collectAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectByteAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectShortAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectUShortAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectLongAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectULongAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectFloatAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectDoubleAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectStringAttribute ( cdevData & userData, int tag, int position );
|
||||
inline void collectTimestampAttribute ( cdevData & userData, int tag, int position );
|
||||
};
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * class rnsQueryCallback :
|
||||
// * This class provides the methods to allow a rnsQueryCollector to be
|
||||
// * incorporated into a cdevCallback. The localCallback function will
|
||||
// * be called with results until the data has been completely collected,
|
||||
// * and only then will the user callback be executed - providing full
|
||||
// * data.
|
||||
// *****************************************************************************
|
||||
class rnsQueryCallback : public cdevCallback
|
||||
{
|
||||
private:
|
||||
rnsQueryCollector collector;
|
||||
cdevCallback callback;
|
||||
|
||||
public:
|
||||
rnsQueryCallback ( cdevCallback & Callback )
|
||||
: cdevCallback(), callback(Callback), collector(*(new cdevData), 1)
|
||||
{
|
||||
userarg_ = this;
|
||||
function_ = rnsQueryCallback::localCallback;
|
||||
}
|
||||
|
||||
virtual ~rnsQueryCallback ( void )
|
||||
{
|
||||
}
|
||||
|
||||
static void localCallback ( int status, void * arg, cdevRequestObject & req, cdevData & data)
|
||||
{
|
||||
rnsQueryCallback * qCallback;
|
||||
|
||||
if((qCallback = (rnsQueryCallback *)arg)!=NULL)
|
||||
{
|
||||
if(status==CDEV_SUCCESS ||
|
||||
status==CDEV_INCOMPLETE)
|
||||
{
|
||||
qCallback->collector.collect(data);
|
||||
}
|
||||
|
||||
if(status==CDEV_SUCCESS ||
|
||||
status==CDEV_ERROR ||
|
||||
status==CDEV_NOTFOUND ||
|
||||
status==CDEV_MSG_ERR)
|
||||
{
|
||||
qCallback->callback.fireCallback(status, qCallback->callback.userarg(),
|
||||
req, *qCallback->collector.getData(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collect :
|
||||
// * This method is called when a cdevData object needs to be appended to
|
||||
// * the cdevData object that is serving as a collection. This method will
|
||||
// * transfer each of the data items in the userData object to the proper
|
||||
// * position in the local data object.
|
||||
// *****************************************************************************
|
||||
int rnsQueryCollector::collect ( cdevData & userData )
|
||||
{
|
||||
int cnt = 0;
|
||||
size_t size = 0;
|
||||
cdevDataIterator iter(&userData);
|
||||
cdevDataIterator dIter(data);
|
||||
|
||||
// *********************************************************************
|
||||
// * Look through the existing data and determine the largest number
|
||||
// * of items that exist in a single tagged item. This value will be
|
||||
// * used to specify the position of the data that is being added to the
|
||||
// * array.
|
||||
// *********************************************************************
|
||||
dIter.init();
|
||||
while(dIter.tag()!=0)
|
||||
{
|
||||
size_t elems = 0;
|
||||
data->getElems(dIter.tag(), &elems);
|
||||
if(elems>size) size = elems;
|
||||
++dIter;
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * Walk through the list of tagged data items that are stored in the
|
||||
// * inbound data object. Call the collectAttribute method for each
|
||||
// * data item. This method will copy the contents of the inbound
|
||||
// * data object to the correct position in the local data object.
|
||||
// *********************************************************************
|
||||
iter.init();
|
||||
while(iter.tag()!=0)
|
||||
{
|
||||
cnt+=(collectAttribute(userData, iter.tag(), size)==0)?1:0;
|
||||
++iter;
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * Return the count of data items that were assimilated into the
|
||||
// * local data object.
|
||||
// *********************************************************************
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectAttribute :
|
||||
// * This method will assimilate a single attribute from the specified
|
||||
// * userData object into the local cdevData object at the specified
|
||||
// * position.
|
||||
// *****************************************************************************
|
||||
int rnsQueryCollector::collectAttribute ( cdevData & userData, int tag, int position )
|
||||
{
|
||||
cdevSystem & sys = cdevSystem::defaultSystem();
|
||||
int result = 0;
|
||||
size_t dim = 0;
|
||||
size_t userDim = 0;
|
||||
cdevDataTypes type = data->getType(tag);
|
||||
cdevDataTypes userType = userData.getType(tag);
|
||||
|
||||
if(userData.getDim(tag, &dim)==CDEV_NOTFOUND || dim > 0)
|
||||
{
|
||||
sys.reportError(CDEV_SEVERITY_ERROR, "Name Server", NULL,
|
||||
"Cannot add array data to query reply");
|
||||
result = -1;
|
||||
}
|
||||
else if(data->getDim(tag, &dim)!=CDEV_NOTFOUND && dim > 1)
|
||||
{
|
||||
sys.reportError(CDEV_SEVERITY_ERROR, "Name Server", NULL,
|
||||
"Cannot assemble a query with multi-dimensional data");
|
||||
result = -1;
|
||||
}
|
||||
else if (userType == CDEV_INVALID)
|
||||
{
|
||||
sys.reportError(CDEV_SEVERITY_ERROR, "Name Server", NULL,
|
||||
"Inbound query data object has invalid data type");
|
||||
result = -1;
|
||||
}
|
||||
else {
|
||||
if(type!=CDEV_INVALID)
|
||||
{
|
||||
if(type<CDEV_TIMESTAMP && userType<CDEV_TIMESTAMP)
|
||||
{
|
||||
type = (type>userType)?type:userType;
|
||||
}
|
||||
else if(type==CDEV_TIMESTAMP) type = userType;
|
||||
}
|
||||
else type = userType;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case CDEV_BYTE:
|
||||
collectByteAttribute(userData, tag, position);
|
||||
break;
|
||||
case CDEV_INT16:
|
||||
collectShortAttribute(userData, tag, position);
|
||||
break;
|
||||
case CDEV_UINT16:
|
||||
collectUShortAttribute(userData, tag, position);
|
||||
break;
|
||||
case CDEV_INT32:
|
||||
collectLongAttribute(userData, tag, position);
|
||||
break;
|
||||
case CDEV_UINT32:
|
||||
collectULongAttribute(userData, tag, position);
|
||||
break;
|
||||
case CDEV_FLOAT:
|
||||
collectFloatAttribute(userData, tag, position);
|
||||
break;
|
||||
case CDEV_DOUBLE:
|
||||
collectDoubleAttribute(userData, tag, position);
|
||||
break;
|
||||
case CDEV_STRING:
|
||||
collectStringAttribute(userData, tag, position);
|
||||
break;
|
||||
case CDEV_TIMESTAMP:
|
||||
collectTimestampAttribute(userData, tag, position);
|
||||
break;
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectByteAttribute :
|
||||
// * This method will transfer the byte attribute stored in the userData
|
||||
// * object into the local cdevData object at the specified position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectByteAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
if((position+1)>byteCnt)
|
||||
{
|
||||
if(byteData!=NULL) delete byteData;
|
||||
byteCnt = ((position+1)>100)?(position+100):100;
|
||||
byteData = new unsigned char [byteCnt];
|
||||
}
|
||||
memset(byteData, 0, byteCnt*sizeof(unsigned char));
|
||||
data->get(tag, byteData);
|
||||
userData.get(tag, &byteData[position]);
|
||||
data->insert(tag, byteData, position+1);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectShortAttribute :
|
||||
// * This method will transfer the short attribute stored in the userData
|
||||
// * object into the local cdevData object at the specified position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectShortAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
if((position+1)>shortCnt)
|
||||
{
|
||||
if(shortData!=NULL) delete shortData;
|
||||
shortCnt = ((position+1)>100)?(position+100):100;
|
||||
shortData = new short [shortCnt];
|
||||
}
|
||||
memset(shortData, 0, shortCnt*sizeof(short));
|
||||
data->get(tag, shortData);
|
||||
userData.get(tag, &shortData[position]);
|
||||
data->insert(tag, shortData, position+1);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectUShortAttribute :
|
||||
// * This method will transfer the unsigned short attribute stored in the
|
||||
// * userData object into the local cdevData object at the specified
|
||||
// * position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectUShortAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
if((position+1)>ushortCnt)
|
||||
{
|
||||
if(ushortData!=NULL) delete ushortData;
|
||||
ushortCnt = ((position+1)>100)?(position+100):100;
|
||||
ushortData = new unsigned short [ushortCnt];
|
||||
}
|
||||
memset(ushortData, 0, ushortCnt*sizeof(unsigned short));
|
||||
data->get(tag, ushortData);
|
||||
userData.get(tag, &ushortData[position]);
|
||||
data->insert(tag, ushortData, position+1);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectLongAttribute :
|
||||
// * This method will transfer the long attribute stored in the
|
||||
// * userData object into the local cdevData object at the specified
|
||||
// * position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectLongAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
if((position+1)>longCnt)
|
||||
{
|
||||
if(longData!=NULL) delete longData;
|
||||
longCnt = ((position+1)>100)?(position+100):100;
|
||||
longData = new long [longCnt];
|
||||
}
|
||||
memset(longData, 0, longCnt*sizeof(long));
|
||||
data->get(tag, longData);
|
||||
userData.get(tag, &longData[position]);
|
||||
data->insert(tag, longData, position+1);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectULongAttribute :
|
||||
// * This method will transfer the unsigned long attribute stored in the
|
||||
// * userData object into the local cdevData object at the specified
|
||||
// * position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectULongAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
if((position+1)>ulongCnt)
|
||||
{
|
||||
if(ulongData!=NULL) delete ulongData;
|
||||
ulongCnt = ((position+1)>100)?(position+100):100;
|
||||
ulongData = new unsigned long [ulongCnt];
|
||||
}
|
||||
memset(ulongData, 0, ulongCnt*sizeof(unsigned long));
|
||||
data->get(tag, ulongData);
|
||||
userData.get(tag, &ulongData[position]);
|
||||
data->insert(tag, ulongData, position+1);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectFloatAttribute :
|
||||
// * This method will transfer the float attribute stored in the
|
||||
// * userData object into the local cdevData object at the specified
|
||||
// * position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectFloatAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
if((position+1)>floatCnt)
|
||||
{
|
||||
if(floatData!=NULL) delete floatData;
|
||||
floatCnt = ((position+1)>100)?(position+100):100;
|
||||
floatData = new float [floatCnt];
|
||||
}
|
||||
memset(floatData, 0, floatCnt*sizeof(float));
|
||||
data->get(tag, floatData);
|
||||
userData.get(tag, &floatData[position]);
|
||||
data->insert(tag, floatData, position+1);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectDoubleAttribute :
|
||||
// * This method will transfer the double attribute stored in the
|
||||
// * userData object into the local cdevData object at the specified
|
||||
// * position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectDoubleAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
if((position+1)>doubleCnt)
|
||||
{
|
||||
if(doubleData!=NULL) delete doubleData;
|
||||
doubleCnt = ((position+1)>100)?(position+100):100;
|
||||
doubleData = new double [doubleCnt];
|
||||
}
|
||||
memset(doubleData, 0, doubleCnt*sizeof(double));
|
||||
data->get(tag, doubleData);
|
||||
userData.get(tag, &doubleData[position]);
|
||||
data->insert(tag, doubleData, position+1);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectStringAttribute :
|
||||
// * This method will transfer the string attribute stored in the
|
||||
// * userData object into the local cdevData object at the specified
|
||||
// * position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectStringAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
int i;
|
||||
char blank = 0;
|
||||
|
||||
char ** stringData = new char * [ position+1 ];
|
||||
memset(stringData, 0, (position+1)*sizeof(char *));
|
||||
data->get(tag, stringData);
|
||||
userData.get(tag, &stringData[position]);
|
||||
|
||||
for(i=0; i<position+1; i++)
|
||||
{
|
||||
if(stringData[i] == NULL) stringData[i] = ␣
|
||||
}
|
||||
data->insert(tag, stringData, position+1);
|
||||
|
||||
for(i=0; i<position+1; i++)
|
||||
{
|
||||
if(stringData[i]!=&blank) delete stringData[i];
|
||||
}
|
||||
delete stringData;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * rnsQueryCollector::collectTimestampAttribute :
|
||||
// * This method will transfer the time stamp attribute stored in the
|
||||
// * userData object into the local cdevData object at the specified
|
||||
// * position.
|
||||
// *****************************************************************************
|
||||
void rnsQueryCollector::collectTimestampAttribute (cdevData & userData, int tag, int position )
|
||||
{
|
||||
if((position+1)>tsCnt)
|
||||
{
|
||||
if(tsData!=NULL) delete tsData;
|
||||
tsCnt = ((position+1)>100)?(position+100):100;
|
||||
tsData = new cdev_TS_STAMP [tsCnt];
|
||||
}
|
||||
memset(tsData, 0, tsCnt);
|
||||
data->get(tag, tsData);
|
||||
userData.get(tag, &tsData[position]);
|
||||
data->insert(tag, tsData, position+1);
|
||||
}
|
||||
@@ -0,0 +1,752 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// Implementation of rnsRequesObject Class
|
||||
//
|
||||
// Author: Jie Chen
|
||||
//
|
||||
// Revision History:
|
||||
// rnsRequestObject.cc,v
|
||||
// Revision 1.7 1998/04/01 15:32:12 chen
|
||||
// fix transaction done flag
|
||||
//
|
||||
// Revision 1.6 1998/03/19 18:31:43 chen
|
||||
// add monitorEntry capability
|
||||
//
|
||||
// Revision 1.5 1998/02/09 13:35:47 chen
|
||||
// duplicate cdev data in the monitor object
|
||||
//
|
||||
// Revision 1.4 1998/02/06 15:11:25 chen
|
||||
// add connection management for name server
|
||||
//
|
||||
// Revision 1.3 1998/02/05 15:59:19 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.2 1998/01/30 18:31:37 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.1 1998/01/22 17:07:51 akers
|
||||
// Addition of new NameServer
|
||||
//
|
||||
//
|
||||
//
|
||||
#include <cdevErrCode.h>
|
||||
#include <cdevCommon.h>
|
||||
#include <rnsMonitorObj.h>
|
||||
#include <cdevClock.h>
|
||||
|
||||
#include "rnsService.h"
|
||||
#include "rnsRequestObject.h"
|
||||
#include "rnsQueryCollector.h"
|
||||
#include <rsvcClient.h>
|
||||
|
||||
char* rnsRequestObject::stags_[] = {"name", "domain"};
|
||||
int rnsRequestObject::numstags_ = 2;
|
||||
|
||||
#ifdef _WIN32
|
||||
inline int strcasecmp ( const char * string1, const char * string2 )
|
||||
{
|
||||
return stricmp(string1, string2);
|
||||
}
|
||||
#endif
|
||||
|
||||
// *****************************************************************************
|
||||
// * The localQuerySynchronizer class has been added to allow me to make
|
||||
// * synchronous requests to query the NameServer.
|
||||
// *****************************************************************************
|
||||
class localQuerySynchronizer
|
||||
{
|
||||
public:
|
||||
static int cbDone;
|
||||
static long cbIdent;
|
||||
static cdevData cbData;
|
||||
static cdevCallback getCallbackObj ( void )
|
||||
{
|
||||
cbData.remove();
|
||||
cbDone = 0;
|
||||
cbIdent++;
|
||||
cdevCallback cbObj(callback, (void *)cbIdent);
|
||||
return cbObj;
|
||||
}
|
||||
static void callback ( int /*status*/, void * userarg, cdevRequestObject &/*reqObj*/, cdevData &data)
|
||||
{
|
||||
if(((long)userarg)==cbIdent)
|
||||
{
|
||||
cbDone = 1;
|
||||
cbData = data;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int localQuerySynchronizer::cbDone = 0;
|
||||
long localQuerySynchronizer::cbIdent = 0;
|
||||
cdevData localQuerySynchronizer::cbData;
|
||||
|
||||
rnsRequestObject::rnsRequestObject (char* device, char* msg,
|
||||
rnsService* svc,
|
||||
cdevSystem& system)
|
||||
:cdevRequestObject (device, msg, system), client_ (0)
|
||||
{
|
||||
#ifdef _TRACE_OBJECTS
|
||||
printf (" Create rnsRequestObject Class Object\n");
|
||||
#endif
|
||||
client_ = &(svc->client_);
|
||||
|
||||
// convert msg to integer action
|
||||
rnsRequestObject::findAction (msg, action_);
|
||||
}
|
||||
|
||||
rnsRequestObject::~rnsRequestObject (void)
|
||||
{
|
||||
#ifdef _TRACE_OBJECTS
|
||||
printf (" Delete rnsRequestObject Class Object\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::getState (void)
|
||||
{
|
||||
if (client_->connected ())
|
||||
return CDEV_STATE_CONNECTED;
|
||||
return CDEV_STATE_NOTCONNECTED;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::sendCallback (cdevData& out, cdevCallback& cbk)
|
||||
{
|
||||
return sendCallback (&out, cbk);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rnsRequestObject::sendCallback (cdevData* out, cdevCallback& userCallback)
|
||||
{
|
||||
if (deferExecution (out, &userCallback))
|
||||
return CDEV_SUCCESS;
|
||||
|
||||
int status = CDEV_SUCCESS;
|
||||
cdevTranObj* xobj = 0;
|
||||
rnsMonitorObj* mobj = 0;
|
||||
rnsService* nservice = (rnsService *)service_;
|
||||
|
||||
// copy userCallback into the following callback, which will free
|
||||
// the user from worrying about cdevCallback object
|
||||
// note: cdevCallback's new operator is an overloaded operator
|
||||
cdevCallback* callback = 0;
|
||||
|
||||
if (client_->connected ()) {
|
||||
switch (action_) {
|
||||
case rnsRequestObject::GET:
|
||||
{
|
||||
if (out == 0)
|
||||
return CDEV_INVALIDARG;
|
||||
|
||||
callback = new cdevCallback (userCallback);
|
||||
xobj = new cdevTranObj (&system_, this, 0, callback);
|
||||
|
||||
rsvcData outdata;
|
||||
if (rnsRequestObject::dataCdevToRsvc (*out, outdata) != CDEV_SUCCESS)
|
||||
status = CDEV_INVALIDARG;
|
||||
else {
|
||||
if (client_->getValue (_RSVC_CDEV_SERVERS, outdata,
|
||||
&(rnsRequestObject::getCallback),
|
||||
(void *)xobj) != CDEV_SUCCESS)
|
||||
status = CDEV_IOFAILED;
|
||||
}
|
||||
if (status != CDEV_SUCCESS)
|
||||
delete xobj;
|
||||
}
|
||||
break;
|
||||
case rnsRequestObject::QUERY:
|
||||
{
|
||||
if (out == 0)
|
||||
return CDEV_INVALIDARG;
|
||||
|
||||
callback = (cdevCallback *)new rnsQueryCallback(userCallback);
|
||||
xobj = new cdevTranObj (&system_, this, 0, callback);
|
||||
mobj = new rnsMonitorObj (*xobj);
|
||||
|
||||
char qmsg[1024];
|
||||
if (out->get ("queryMsg", qmsg, sizeof (qmsg)) != CDEV_SUCCESS)
|
||||
status = CDEV_INVALIDARG;
|
||||
else {
|
||||
mobj->out_ = new cdevData (*out);
|
||||
if (client_->query (_RSVC_CDEV_SERVERS, qmsg,
|
||||
&(rnsRequestObject::queryCallback),
|
||||
(void *)mobj) != CDEV_SUCCESS)
|
||||
status = CDEV_IOFAILED;
|
||||
else
|
||||
nservice->addMonitorObject (mobj);
|
||||
}
|
||||
if (status != CDEV_SUCCESS) {
|
||||
delete xobj;
|
||||
delete mobj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case rnsRequestObject::MONITORON:
|
||||
{
|
||||
if (out == 0)
|
||||
return CDEV_INVALIDARG;
|
||||
|
||||
if (nservice->hasCallback (userCallback))
|
||||
return CDEV_INVALIDARG;
|
||||
|
||||
callback = new cdevCallback (userCallback);
|
||||
xobj = new cdevTranObj (&system_, this, 0, callback);
|
||||
mobj = new rnsMonitorObj (*xobj);
|
||||
|
||||
|
||||
rsvcData outdata;
|
||||
if (rnsRequestObject::dataCdevToRsvc (*out, outdata) != CDEV_SUCCESS)
|
||||
status = CDEV_INVALIDARG;
|
||||
else {
|
||||
mobj->out_ = new cdevData (*out);
|
||||
if (client_->monitorValue (_RSVC_CDEV_SERVERS, outdata,
|
||||
&(rnsRequestObject::monitorCallback),
|
||||
(void *)mobj) != CDEV_SUCCESS)
|
||||
status = CDEV_IOFAILED;
|
||||
else
|
||||
nservice->addMonitorObject (mobj);
|
||||
}
|
||||
if (status != CDEV_SUCCESS) {
|
||||
delete xobj;
|
||||
delete mobj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case rnsRequestObject::MONITOROFF:
|
||||
{
|
||||
if (out == 0)
|
||||
return CDEV_INVALIDARG;
|
||||
|
||||
rnsMonitorObj* mobj = 0;
|
||||
rsvcData outdata;
|
||||
if (rnsRequestObject::dataCdevToRsvc (*out, outdata) != CDEV_SUCCESS)
|
||||
status = CDEV_INVALIDARG;
|
||||
else {
|
||||
if ((mobj = nservice->hasCallback (userCallback)) == 0) {
|
||||
printf ("this callback function is not registered\n");
|
||||
status = CDEV_INVALIDARG;
|
||||
}
|
||||
else
|
||||
status = monitorOff (outdata, mobj);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case rnsRequestObject::MONITORENTRY:
|
||||
{
|
||||
if (nservice->hasCallback (userCallback))
|
||||
return CDEV_INVALIDARG;
|
||||
|
||||
callback = new cdevCallback (userCallback);
|
||||
xobj = new cdevTranObj (&system_, this, 0, callback);
|
||||
mobj = new rnsMonitorObj (*xobj);
|
||||
|
||||
rsvcData empty;
|
||||
if (client_->monitorIncomingEntries (_RSVC_CDEV_SERVERS, empty,
|
||||
&(rnsRequestObject::entryCallback),
|
||||
(void *)mobj) != CDEV_SUCCESS)
|
||||
status = CDEV_IOFAILED;
|
||||
else
|
||||
nservice->addMonitorObject (mobj);
|
||||
|
||||
if (status != CDEV_SUCCESS) {
|
||||
delete xobj;
|
||||
delete mobj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case rnsRequestObject::MONITORENTRYOFF:
|
||||
{
|
||||
rnsMonitorObj* mobj = 0;
|
||||
if ((mobj = nservice->hasCallback (userCallback)) == 0) {
|
||||
#ifdef _CDEV_DEBUG
|
||||
printf ("this callback function is not registered\n");
|
||||
#endif
|
||||
status = CDEV_INVALIDARG;
|
||||
}
|
||||
else
|
||||
status = monitorEntryOff (mobj);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = CDEV_INVALIDARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
status = CDEV_NOTCONNECTED;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::sendMonitor (rnsMonitorObj* mobj)
|
||||
{
|
||||
rsvcData outdata;
|
||||
int status = CDEV_SUCCESS;
|
||||
|
||||
if (rnsRequestObject::dataCdevToRsvc (*mobj->out_, outdata)!= CDEV_SUCCESS) {
|
||||
mobj->started_ = 1;
|
||||
status = CDEV_INVALIDARG;
|
||||
}
|
||||
else {
|
||||
if ((status = client_->monitorValue (_RSVC_CDEV_SERVERS, outdata,
|
||||
&(rnsRequestObject::monitorCallback),
|
||||
(void *)mobj)) != CDEV_SUCCESS)
|
||||
mobj->started_ = 1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::sendEntryMonitor (rnsMonitorObj* mobj)
|
||||
{
|
||||
int status = CDEV_SUCCESS;
|
||||
rsvcData empty;
|
||||
|
||||
if ((status = client_->monitorIncomingEntries (_RSVC_CDEV_SERVERS, empty,
|
||||
&(rnsRequestObject::entryCallback),
|
||||
(void *)mobj)) != CDEV_SUCCESS)
|
||||
mobj->started_ = 1;
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
rnsRequestObject::getCallback (int status, void* arg, rsvcData* data)
|
||||
{
|
||||
cdevTranObj* xobj = (cdevTranObj *)arg;
|
||||
|
||||
|
||||
// if a callback has been discarded, do not do anything
|
||||
if (xobj->isTrash ()) {
|
||||
delete xobj;
|
||||
return;
|
||||
}
|
||||
|
||||
cdevCallback* cbk = xobj->userCallback_;
|
||||
cdevRequestObject* obj = xobj->reqObj_;
|
||||
cdevData* rda = xobj->resultData_;
|
||||
cdevData result;
|
||||
|
||||
if (rda) // send no block
|
||||
rda->remove ();
|
||||
else
|
||||
rda = &result;
|
||||
|
||||
if (status == RSVC_SUCCESS)
|
||||
rnsRequestObject::dataRsvcToCdev (*data, *rda);
|
||||
|
||||
if (cbk)
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 0);
|
||||
|
||||
delete xobj;
|
||||
}
|
||||
|
||||
void
|
||||
rnsRequestObject::queryCallback (int status, void* arg, rsvcData* data)
|
||||
{
|
||||
rnsMonitorObj* mobj = (rnsMonitorObj *)arg;
|
||||
|
||||
cdevCallback* cbk = mobj->userCallback_;
|
||||
cdevRequestObject* obj = mobj->reqObj_;
|
||||
cdevData result;
|
||||
int cbk_finished = 1;
|
||||
|
||||
// first time this callback is called
|
||||
if (mobj->tobj_) {
|
||||
delete mobj->tobj_;
|
||||
mobj->tobj_ = 0;
|
||||
}
|
||||
|
||||
if (status == RSVC_ERROR || status == RSVC_NOTFOUND)
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 0);
|
||||
else if (status == RSVC_INCOMPLETE) {
|
||||
rnsRequestObject::dataRsvcToCdev (*data, result);
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 1);
|
||||
cbk_finished = 0;
|
||||
}
|
||||
else if (status == RSVC_QUERYMSG_ERR)
|
||||
cbk->fireCallback (CDEV_MSG_ERR, cbk->userarg (), *obj, result, 0);
|
||||
else {
|
||||
rnsRequestObject::dataRsvcToCdev (*data, result);
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 0);
|
||||
}
|
||||
if (cbk_finished) {
|
||||
rnsRequestObject* nsreq = (rnsRequestObject *)obj;
|
||||
nsreq->removeMonitorObject (mobj);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rnsRequestObject::monitorCallback (int status, void* arg, rsvcData* data)
|
||||
{
|
||||
rnsMonitorObj* mobj = (rnsMonitorObj *)arg;
|
||||
|
||||
cdevCallback* cbk = mobj->userCallback_;
|
||||
cdevRequestObject* obj = mobj->reqObj_;
|
||||
cdevData result;
|
||||
int cbk_finished = 1;
|
||||
|
||||
// first time this callback is called
|
||||
if (mobj->tobj_) {
|
||||
delete mobj->tobj_;
|
||||
mobj->tobj_ = 0;
|
||||
}
|
||||
|
||||
if (status == RSVC_SUCCESS) {
|
||||
rnsRequestObject::dataRsvcToCdev (*data, result);
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 1);
|
||||
cbk_finished = 0;
|
||||
if (!mobj->started_)
|
||||
mobj->started_ = 1;
|
||||
}
|
||||
else if (status == RSVC_CBK_FINISHED) {
|
||||
rnsRequestObject::dataRsvcToCdev (*data, result);
|
||||
if (mobj->started_)
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 0);
|
||||
}
|
||||
else {
|
||||
if (mobj->started_)
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 0);
|
||||
}
|
||||
|
||||
if (cbk_finished && mobj->started_) {
|
||||
rnsRequestObject* nsreq = (rnsRequestObject *)obj;
|
||||
nsreq->removeMonitorObject (mobj);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rnsRequestObject::entryCallback (int status, void* arg, rsvcData* data)
|
||||
{
|
||||
rnsMonitorObj* mobj = (rnsMonitorObj *)arg;
|
||||
|
||||
cdevCallback* cbk = mobj->userCallback_;
|
||||
cdevRequestObject* obj = mobj->reqObj_;
|
||||
cdevData result;
|
||||
int cbk_finished = 1;
|
||||
|
||||
// first time this callback is called
|
||||
if (mobj->tobj_) {
|
||||
delete mobj->tobj_;
|
||||
mobj->tobj_ = 0;
|
||||
}
|
||||
|
||||
if (status == RSVC_SUCCESS || status == RSVC_INCOMPLETE) {
|
||||
rnsRequestObject::dataRsvcToCdev (*data, result);
|
||||
cbk->fireCallback (RSVC_SUCCESS, cbk->userarg (), *obj, result, 1);
|
||||
cbk_finished = 0;
|
||||
if (!mobj->started_)
|
||||
mobj->started_ = 1;
|
||||
}
|
||||
else if (status == RSVC_CBK_FINISHED) {
|
||||
rnsRequestObject::dataRsvcToCdev (*data, result);
|
||||
if (mobj->started_)
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 0);
|
||||
}
|
||||
else {
|
||||
if (mobj->started_)
|
||||
cbk->fireCallback (status, cbk->userarg (), *obj, result, 1);
|
||||
}
|
||||
|
||||
if (cbk_finished && mobj->started_) {
|
||||
rnsRequestObject* nsreq = (rnsRequestObject *)obj;
|
||||
nsreq->removeMonitorObject (mobj);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::monitorOff (rsvcData& data, rnsMonitorObj* mobj)
|
||||
{
|
||||
int status;
|
||||
status = client_->monitorOffValue (_RSVC_CDEV_SERVERS, data,
|
||||
&(rnsRequestObject::monitorCallback),
|
||||
(void *)mobj);
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::monitorEntryOff (rnsMonitorObj* mobj)
|
||||
{
|
||||
int status;
|
||||
rsvcData empty;
|
||||
status = client_->monitorOffIncomingEntries (_RSVC_CDEV_SERVERS, empty,
|
||||
&(rnsRequestObject::entryCallback),
|
||||
(void *)mobj);
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::sendNoBlock (cdevData& out, cdevData& result)
|
||||
{
|
||||
return sendNoBlock (&out, &result);
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::sendNoBlock (cdevData* out, cdevData& result)
|
||||
{
|
||||
return sendNoBlock (out, &result);
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::sendNoBlock (cdevData& out, cdevData* result)
|
||||
{
|
||||
return sendNoBlock (&out, result);
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::sendNoBlock (cdevData* out, cdevData* result)
|
||||
{
|
||||
if (deferExecution (out, result))
|
||||
return CDEV_SUCCESS;
|
||||
|
||||
int status = CDEV_SUCCESS;
|
||||
cdevTranObj* xobj = 0;
|
||||
rnsService* nservice = (rnsService *)service_;
|
||||
|
||||
if (client_->connected ()) {
|
||||
switch (action_) {
|
||||
case rnsRequestObject::GET:
|
||||
{
|
||||
if (out == 0 || result == 0)
|
||||
return CDEV_INVALIDARG;
|
||||
|
||||
xobj = new cdevTranObj (&system_, this, result, 0);
|
||||
|
||||
rsvcData outdata;
|
||||
if (rnsRequestObject::dataCdevToRsvc (*out, outdata) != CDEV_SUCCESS)
|
||||
status = CDEV_INVALIDARG;
|
||||
else {
|
||||
if (client_->getValue (_RSVC_CDEV_SERVERS, outdata,
|
||||
&(rnsRequestObject::getCallback),
|
||||
(void *)xobj) != CDEV_SUCCESS)
|
||||
status = CDEV_IOFAILED;
|
||||
}
|
||||
if (status != CDEV_SUCCESS)
|
||||
delete xobj;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = CDEV_INVALIDARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
status = CDEV_NOTCONNECTED;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::send (cdevData& out, cdevData& result)
|
||||
{
|
||||
return send (&out, &result);
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::send (cdevData* out, cdevData& result)
|
||||
{
|
||||
return send (out, &result);
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::send (cdevData& out, cdevData* result)
|
||||
{
|
||||
return send (&out, result);
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::send (cdevData* out, cdevData* result)
|
||||
{
|
||||
int status = CDEV_SUCCESS;
|
||||
rnsService* nservice = (rnsService *)service_;
|
||||
|
||||
if (client_->connected ()) {
|
||||
switch (action_) {
|
||||
case rnsRequestObject::GET:
|
||||
if (out == 0 || result == 0)
|
||||
status = CDEV_INVALIDARG;
|
||||
else {
|
||||
cdevGroup grp (2, system_);
|
||||
grp.start ();
|
||||
sendNoBlock (out, result);
|
||||
grp.end ();
|
||||
grp.pend (4.0);
|
||||
if (!grp.allFinished ())
|
||||
status = CDEV_TIMEOUT;
|
||||
}
|
||||
break;
|
||||
case rnsRequestObject::QUERY:
|
||||
if(out==0 || result==0)
|
||||
status = CDEV_INVALIDARG;
|
||||
else {
|
||||
cdevCallback cb = localQuerySynchronizer::getCallbackObj();
|
||||
if((status=sendCallback(out, cb))==CDEV_SUCCESS)
|
||||
{
|
||||
cdevTimeValue t(5.0);
|
||||
cdevClock timer;
|
||||
timer.schedule(NULL, t);
|
||||
|
||||
while(!localQuerySynchronizer::cbDone && !timer.expired()) nservice->poll();
|
||||
|
||||
if(!localQuerySynchronizer::cbDone) status = CDEV_TIMEOUT;
|
||||
else *result = localQuerySynchronizer::cbData;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = CDEV_INVALIDARG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
status = CDEV_NOTCONNECTED;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::dataCdevToRsvc (cdevData& data, rsvcData& res)
|
||||
{
|
||||
char val[1024];
|
||||
for (int i = 0; i < rnsRequestObject::numstags_; i++) {
|
||||
if (data.get (rnsRequestObject::stags_[i], val, sizeof (val))
|
||||
!= CDEV_SUCCESS)
|
||||
return CDEV_ERROR;
|
||||
|
||||
res.insert (rnsRequestObject::stags_[i], val);
|
||||
}
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rnsRequestObject::dataRsvcToCdev (rsvcData& data, cdevData& res)
|
||||
{
|
||||
rsvcDataIterator ite (&data);
|
||||
int type;
|
||||
int tag;
|
||||
size_t numelems;
|
||||
size_t dim;
|
||||
char* ctag;
|
||||
|
||||
for (ite.init (); !ite ; ++ite) {
|
||||
ctag = (char *)ite.tag ();
|
||||
type = data.getType (ctag);
|
||||
data.getElems (ctag, &numelems);
|
||||
data.getDim (ctag, &dim);
|
||||
|
||||
if (cdevData::tagC2I (ctag, &tag) != CDEV_SUCCESS || dim > 1)
|
||||
continue;
|
||||
|
||||
switch (type) {
|
||||
case RSVC_BYTE:
|
||||
case RSVC_INT16:
|
||||
case RSVC_UINT16:
|
||||
case RSVC_INT32:
|
||||
case RSVC_UINT32:
|
||||
{
|
||||
if (dim == 0) {
|
||||
int val;
|
||||
data.get (ctag, &val);
|
||||
res.insert (tag, val);
|
||||
}
|
||||
else {
|
||||
int* val = new int[numelems];
|
||||
data.get (ctag, val);
|
||||
res.insert (tag, val, numelems);
|
||||
delete []val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RSVC_FLOAT:
|
||||
{
|
||||
if (dim == 0) {
|
||||
float val;
|
||||
data.get (ctag, &val);
|
||||
res.insert (tag, val);
|
||||
}
|
||||
else {
|
||||
float* val = new float[numelems];
|
||||
data.get (ctag, val);
|
||||
res.insert (tag, val, numelems);
|
||||
delete []val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RSVC_DOUBLE:
|
||||
{
|
||||
if (dim == 0) {
|
||||
double val;
|
||||
data.get (ctag, &val);
|
||||
res.insert (tag, val);
|
||||
}
|
||||
else {
|
||||
double* val = new double[numelems];
|
||||
data.get (ctag, val);
|
||||
res.insert (tag, val, numelems);
|
||||
delete []val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RSVC_STRING:
|
||||
{
|
||||
if (dim == 0) {
|
||||
char val[1024];
|
||||
data.get (ctag, val, sizeof (val));
|
||||
res.insert (tag, val);
|
||||
}
|
||||
else {
|
||||
char** val = new char*[numelems];
|
||||
data.get (ctag, val);
|
||||
res.insert (tag, val, numelems);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::removeMonitorObject (rnsMonitorObj* mobj)
|
||||
{
|
||||
rnsService *nservice = (rnsService *)service_;
|
||||
|
||||
nservice->removeMonitorObject (mobj);
|
||||
delete mobj;
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
rnsRequestObject::findAction (char* msg, int& action)
|
||||
{
|
||||
if (strcasecmp (msg, "query") == 0)
|
||||
action = rnsRequestObject::QUERY;
|
||||
else if (strcasecmp (msg, "get") == 0)
|
||||
action = rnsRequestObject::GET;
|
||||
else if (strcasecmp (msg, "monitorOn") == 0)
|
||||
action = rnsRequestObject::MONITORON;
|
||||
else if (strcasecmp (msg, "monitorOff") == 0)
|
||||
action = rnsRequestObject::MONITOROFF;
|
||||
else if (strcasecmp (msg, "monitorEntry") == 0)
|
||||
action = rnsRequestObject::MONITORENTRY;
|
||||
else if (strcasecmp (msg, "monitorEntryOff") == 0)
|
||||
action = rnsRequestObject::MONITORENTRYOFF;
|
||||
else
|
||||
action = rnsRequestObject::UNKNOWN;
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// CDEV Resource Name Service Request Object
|
||||
//
|
||||
// Author: Jie Chen
|
||||
//
|
||||
//
|
||||
//
|
||||
#ifndef _RNS_REQUEST_OBJECT_H
|
||||
#define _RNS_REQUEST_OBJECT_H
|
||||
|
||||
#include <cdevSystem.h>
|
||||
#include <cdevRequestObject.h>
|
||||
|
||||
class rsvcClient;
|
||||
class rnsService;
|
||||
class rnsMonitorObj;
|
||||
|
||||
class rnsRequestObject: public cdevRequestObject
|
||||
{
|
||||
public:
|
||||
// constructor and destructor
|
||||
rnsRequestObject (char* device,
|
||||
char* msg,
|
||||
rnsService* svc,
|
||||
cdevSystem& system = cdevSystem::defaultSystem());
|
||||
~rnsRequestObject (void);
|
||||
|
||||
int send (cdevData& out, cdevData& result);
|
||||
int send (cdevData *out, cdevData& result);
|
||||
int send (cdevData& out, cdevData* result);
|
||||
int send (cdevData *out, cdevData* result);
|
||||
// PURPOSE: Synchronous IO operations
|
||||
// REQUIRE: When do query and get, result must be provided
|
||||
// PROMISE: return CDEV_SUCCESS: success.
|
||||
|
||||
int sendNoBlock (cdevData& out, cdevData& result);
|
||||
int sendNoBlock (cdevData* out, cdevData& result);
|
||||
int sendNoBlock (cdevData& out, cdevData* result);
|
||||
int sendNoBlock (cdevData* out, cdevData* result);
|
||||
// PURPOSE: Asynchronous IO operations used in conjunction with
|
||||
// cdevGroup or system
|
||||
// REQUIRE:
|
||||
// PROMISE: return CDEV_SUCCESS: requests have been sent out.
|
||||
|
||||
int sendCallback (cdevData& out, cdevCallback& callback);
|
||||
int sendCallback (cdevData* out, cdevCallback& callback);
|
||||
// PURPOSE: Asynchromous IO operations with a user supplied callback function
|
||||
// REQUIRE:
|
||||
// PROMISE: User callback function will be called with status information
|
||||
// status = CDEV_DISCONNECTED: channel discconected
|
||||
// status = CDEV_SUCCESS : everything is OK
|
||||
// status = CDEV_ERROR : something fishy.
|
||||
// status = CDEV_INCOMPLETE : data flow will coming (88)
|
||||
// status = CDEV_CBK_FINISHED: query callback finished (89)
|
||||
// status = CDEV_QUERYMSG_ERR: query message syntax erro (91)
|
||||
|
||||
int getState (void);
|
||||
// PURPOSE: get connection state
|
||||
// REQUIRE: none
|
||||
// PROMISE: CDEV_CONNECTED or CDEV_NOTCONNECTED
|
||||
|
||||
const char *className (void) const {return "rnsRequestObject";}
|
||||
|
||||
protected:
|
||||
// find out action from message
|
||||
static int findAction (char* msg, int& action);
|
||||
|
||||
// action value
|
||||
typedef enum {GET = 0x2000,QUERY,MONITORON,MONITOROFF,
|
||||
MONITORENTRY, MONITORENTRYOFF, UNKNOWN} RNSENUMVERB;
|
||||
|
||||
// get value callback
|
||||
static void getCallback (int status, void* arg, rsvcData* data);
|
||||
|
||||
// query value callback
|
||||
static void queryCallback (int status, void* arg, rsvcData* data);
|
||||
|
||||
// monitor value callback
|
||||
static void monitorCallback (int status, void* arg, rsvcData* data);
|
||||
|
||||
// monitor entry callback
|
||||
static void entryCallback (int status, void* arg, rsvcData* data);
|
||||
|
||||
// data conversion from rsvc to cdev
|
||||
static int dataRsvcToCdev (rsvcData& data, cdevData& result);
|
||||
|
||||
// data conversion from cdev to rsvc
|
||||
static int dataCdevToRsvc (cdevData& data, rsvcData& result);
|
||||
|
||||
// remove a monitor object
|
||||
int removeMonitorObject (rnsMonitorObj* mobj);
|
||||
|
||||
// monitor off a callback
|
||||
int monitorOff (rsvcData& data, rnsMonitorObj* obj);
|
||||
|
||||
// monitor off entry callback
|
||||
int monitorEntryOff (rnsMonitorObj* obj);
|
||||
|
||||
// resend a monitor callback
|
||||
int sendMonitor (rnsMonitorObj* mobj);
|
||||
|
||||
// resend a monitor entry callback
|
||||
int sendEntryMonitor (rnsMonitorObj* mobj);
|
||||
|
||||
private:
|
||||
|
||||
// two tags are needed for all serachs
|
||||
static char* stags_[];
|
||||
static int numstags_;
|
||||
|
||||
// action type
|
||||
int action_;
|
||||
|
||||
// pointer of underlying client connection
|
||||
rsvcClient* client_;
|
||||
|
||||
// friend class
|
||||
friend class rnsService;
|
||||
|
||||
};
|
||||
#endif
|
||||
+383
@@ -0,0 +1,383 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// Implementation of nsService Class
|
||||
//
|
||||
// Author: Jie Chen
|
||||
//
|
||||
// Revision History:
|
||||
// rnsService.cc,v
|
||||
// Revision 1.8 1998/03/19 18:31:43 chen
|
||||
// add monitorEntry capability
|
||||
//
|
||||
// Revision 1.7 1998/02/23 16:29:35 chen
|
||||
// change back to use alarm to handle reconnecton to the name server
|
||||
//
|
||||
// Revision 1.6 1998/02/19 18:39:52 akers
|
||||
// Bug Fixes
|
||||
//
|
||||
// Revision 1.5 1998/02/18 14:42:52 chen
|
||||
// add registerFd to the service
|
||||
//
|
||||
// Revision 1.4 1998/02/10 18:06:44 chen
|
||||
// use system timer instead of alarm
|
||||
//
|
||||
// Revision 1.3 1998/02/06 15:11:26 chen
|
||||
// add connection management for name server
|
||||
//
|
||||
// Revision 1.2 1998/01/30 18:31:37 akers
|
||||
// Ongoing development
|
||||
//
|
||||
// Revision 1.1 1998/01/22 17:07:52 akers
|
||||
// Addition of new NameServer
|
||||
//
|
||||
//
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "rnsService.h"
|
||||
#include "rnsRequestObject.h"
|
||||
#include <rnsMonitorObj.h>
|
||||
|
||||
#define _RNS_CLIENT_RECONN_TIMEOUT 5
|
||||
|
||||
char * rnsService::tags_[] = {
|
||||
"table",
|
||||
"key",
|
||||
"keyExp",
|
||||
"keyType",
|
||||
"name",
|
||||
"domain",
|
||||
"host",
|
||||
"owner",
|
||||
"time",
|
||||
"port",
|
||||
"pid",
|
||||
"ping",
|
||||
"client",
|
||||
"queryMsg"
|
||||
};
|
||||
|
||||
int rnsService::numtags_ = 14;
|
||||
|
||||
static rnsService* _rnsNameService_ = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
void CALLBACK _rnsAlarmHandler_ ( HWND hwnd, UINT umsg, UINT idEvent, DWORD dwTime )
|
||||
{
|
||||
if (_rnsNameService_->reconnect () == CDEV_SUCCESS)
|
||||
{
|
||||
if (_rnsNameService_->monitorsRestarted ())
|
||||
{
|
||||
KillTimer(NULL, idEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static struct sigaction _oldaction_;
|
||||
|
||||
static void _rnsAlarmHandler_ (int /* signo */)
|
||||
{
|
||||
int done = 0;
|
||||
|
||||
if (_rnsNameService_->reconnect () == CDEV_SUCCESS) {
|
||||
if (_rnsNameService_->monitorsRestarted ()) {
|
||||
sigaction (SIGALRM, &_oldaction_, 0);
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!done)
|
||||
alarm (_RNS_CLIENT_RECONN_TIMEOUT);
|
||||
}
|
||||
#endif
|
||||
|
||||
rnsService::rnsService (char* name, cdevSystem& system)
|
||||
:cdevService (name, system), client_ (), fds_ (0), numFds_ (0),
|
||||
monobjs_ ()
|
||||
{
|
||||
#ifdef _TRACE_OBJECTS
|
||||
printf (" Create rnsService Class Object\n");
|
||||
#endif
|
||||
// register all tags
|
||||
for (int i = 0; i < rnsService::numtags_; i++)
|
||||
cdevData::addTag (rnsService::tags_[i]);
|
||||
|
||||
// remember this service
|
||||
_rnsNameService_ = this;
|
||||
}
|
||||
|
||||
rnsService::~rnsService (void)
|
||||
{
|
||||
#ifdef _TRACE_OBJECTS
|
||||
printf (" Delete rnsService Class Object\n");
|
||||
#endif
|
||||
if (client_.connected ())
|
||||
client_.disconnect ();
|
||||
|
||||
if (numFds_ > 0)
|
||||
delete []fds_;
|
||||
|
||||
// delete all callbacks
|
||||
cdevSlistIterator ite (monobjs_);
|
||||
rnsMonitorObj* mobj = 0;
|
||||
|
||||
for (ite.init (); !ite; ++ite) {
|
||||
mobj = (rnsMonitorObj *) ite ();
|
||||
delete mobj;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::getFd (int* &fd, int& numFd)
|
||||
{
|
||||
fd = fds_;
|
||||
numFd = numFds_;
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::flush (void)
|
||||
{
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rnsService::poll (void)
|
||||
{
|
||||
return client_.pendIO (0.001);
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::pend (int /* fd */)
|
||||
{
|
||||
return client_.pendIO ();
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::pend (double seconds, int)
|
||||
{
|
||||
return client_.pendIO (seconds);
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::getRequestObject (char* deviceName, char* msg,
|
||||
cdevRequestObject* &req)
|
||||
{
|
||||
if (!client_.connected ()) {
|
||||
char* nsHost = getenv ("CDEV_NAME_SERVER");
|
||||
if (!nsHost) {
|
||||
reportError (CDEV_SEVERITY_SEVERE, serviceName_, 0,
|
||||
"Cannot find environment variable CDEV_NAME_SERVER !!!");
|
||||
req = 0;
|
||||
return CDEV_ERROR;
|
||||
}
|
||||
if (client_.connect (nsHost, RSVC_SERVER_PORT, 3.0) != RSVC_SUCCESS) {
|
||||
reportError (CDEV_SEVERITY_SEVERE, serviceName_, 0,
|
||||
"Cannot connect to name server at port %d on %s",
|
||||
RSVC_SERVER_PORT, nsHost);
|
||||
req = 0;
|
||||
return CDEV_ERROR;
|
||||
}
|
||||
|
||||
if (numFds_ > 0)
|
||||
delete []fds_;
|
||||
|
||||
fds_ = new int[1];
|
||||
numFds_ = 1;
|
||||
fds_[0] = client_.getFd ();
|
||||
|
||||
// register fd to the system
|
||||
registerFd (client_.getFd (), 1);
|
||||
|
||||
// register a disconnection callback
|
||||
if (client_.disconnectCallback (&(rnsService::discCallback),
|
||||
(void *)this) != RSVC_SUCCESS)
|
||||
reportError (CDEV_SEVERITY_WARN, serviceName_, 0,
|
||||
"Cannot register disconnect callback");
|
||||
}
|
||||
req = new rnsRequestObject (deviceName, msg, this, system_);
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::reconnect (void)
|
||||
{
|
||||
char* nsHost = getenv ("CDEV_NAME_SERVER");
|
||||
if (!client_.connected ()) {
|
||||
if (client_.connect (nsHost, RSVC_SERVER_PORT, 3.0) == RSVC_SUCCESS) {
|
||||
reportError (CDEV_SEVERITY_INFO, serviceName_, 0,
|
||||
"Reconnected to name server at port %d on %s",
|
||||
RSVC_SERVER_PORT, nsHost);
|
||||
|
||||
fds_ = new int[1];
|
||||
numFds_ = 1;
|
||||
fds_[0] = client_.getFd ();
|
||||
|
||||
// register this fd to the sysem
|
||||
registerFd (client_.getFd(), 1);
|
||||
|
||||
// register a disconnection callback
|
||||
if (client_.disconnectCallback (&(rnsService::discCallback),
|
||||
(void *)this) != RSVC_SUCCESS)
|
||||
reportError (CDEV_SEVERITY_WARN, serviceName_, 0,
|
||||
"Cannot register disconnect callback");
|
||||
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
else
|
||||
return CDEV_TIMEOUT;
|
||||
}
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::getNameServer (cdevDevice* &ns)
|
||||
{
|
||||
ns = 0;
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
cdevService *
|
||||
newRnsService (char* name, cdevSystem* system)
|
||||
{
|
||||
return new rnsService (name, *system);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rnsService::addMonitorObject (rnsMonitorObj* obj)
|
||||
{
|
||||
cdevSlistIterator ite (monobjs_);
|
||||
rnsMonitorObj* mobj = 0;
|
||||
|
||||
for (ite.init (); !ite; ++ite) {
|
||||
mobj = (rnsMonitorObj *) ite ();
|
||||
if (*(mobj->userCallback_) == *(obj->userCallback_))
|
||||
return CDEV_ERROR;
|
||||
}
|
||||
monobjs_.add ((void *)obj);
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::removeMonitorObject (rnsMonitorObj* obj)
|
||||
{
|
||||
cdevSlistIterator ite (monobjs_);
|
||||
rnsMonitorObj* mobj = 0;
|
||||
int found = 0;
|
||||
|
||||
for (ite.init (); !ite; ++ite) {
|
||||
mobj = (rnsMonitorObj *) ite ();
|
||||
if (mobj == obj) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
monobjs_.remove ((void *)obj);
|
||||
return CDEV_SUCCESS;
|
||||
}
|
||||
return CDEV_ERROR;
|
||||
}
|
||||
|
||||
rnsMonitorObj*
|
||||
rnsService::hasCallback (cdevCallback& cbk)
|
||||
{
|
||||
cdevSlistIterator ite (monobjs_);
|
||||
rnsMonitorObj* mobj = 0;
|
||||
|
||||
for (ite.init (); !ite; ++ite) {
|
||||
mobj = (rnsMonitorObj *) ite ();
|
||||
if (*(mobj->userCallback_) == cbk)
|
||||
return mobj;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rnsService::monitorsRestarted (void)
|
||||
{
|
||||
cdevSlistIterator ite (monobjs_);
|
||||
rnsMonitorObj* mobj = 0;
|
||||
rnsRequestObject* req = 0;
|
||||
int notdone = 0;
|
||||
|
||||
for (ite.init (); !ite; ++ite) {
|
||||
mobj = (rnsMonitorObj *)ite ();
|
||||
if (!mobj->started_) {
|
||||
notdone = 1;
|
||||
req = (rnsRequestObject *)mobj->reqObj_;
|
||||
if (req->action_ == rnsRequestObject::MONITORON)
|
||||
req->sendMonitor (mobj);
|
||||
else if (req->action_ == rnsRequestObject::MONITORENTRY)
|
||||
req->sendEntryMonitor (mobj);
|
||||
}
|
||||
}
|
||||
return !notdone;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rnsService::discCallback (int /* status */, void* arg, rsvcData* /* data */)
|
||||
{
|
||||
rnsService* nsvc = (rnsService *) arg;
|
||||
|
||||
if (nsvc->numFds_ > 0) {
|
||||
// remove this fd from the system
|
||||
for (int i = 0; i < nsvc->numFds_; i++)
|
||||
nsvc->registerFd (nsvc->fds_[i], 0);
|
||||
|
||||
delete [](nsvc->fds_);
|
||||
nsvc->numFds_ = 0;
|
||||
}
|
||||
|
||||
cdevSlistIterator ite (nsvc->monobjs_);
|
||||
rnsMonitorObj* mobj = 0;
|
||||
cdevCallback* cbk = 0;
|
||||
cdevRequestObject *req = 0;
|
||||
cdevData empty;
|
||||
|
||||
for (ite.init (); !ite; ++ite) {
|
||||
mobj = (rnsMonitorObj *) ite ();
|
||||
|
||||
cbk = mobj->userCallback_;
|
||||
req = mobj->reqObj_;
|
||||
cbk->fireCallback (CDEV_DISCONNECTED, cbk->userarg (),
|
||||
*req, empty, 0);
|
||||
mobj->started_ = 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
SetTimer (NULL, 0, 1000*_RNS_CLIENT_RECONN_TIMEOUT, _rnsAlarmHandler_);
|
||||
#else
|
||||
// register a alarm handler to try to connect to the name server
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_handler = _rnsAlarmHandler_;
|
||||
sigemptyset (&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
|
||||
if (sigaction (SIGALRM, &act, &_oldaction_) < 0)
|
||||
cdevSystem::defaultSystem().reportError(
|
||||
CDEV_SEVERITY_ERROR, "RNS Service", NULL,
|
||||
"Cannot register alarm signal handler");
|
||||
else
|
||||
alarm (_RNS_CLIENT_RECONN_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
|
||||
// Continuous Electron Beam Accelerator Facility
|
||||
//
|
||||
// This software was developed under a United States Government license
|
||||
// described in the NOTICE file included as part of this distribution.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description:
|
||||
// Implementation of cdev interface to resouce service client
|
||||
//
|
||||
// This is only a subset of whole APIs of rsvc client
|
||||
//
|
||||
// Author: Jie Chen
|
||||
//
|
||||
//
|
||||
//
|
||||
#ifndef _NS_SERVICE_H
|
||||
#define _NS_SERVICE_H
|
||||
|
||||
#ifndef _CDEV_MANAGE_SERVERS
|
||||
#define _CDEV_MANAGE_SERVERS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cdevService.h>
|
||||
#include <cdevRequestObject.h>
|
||||
#include <cdevSlist.h>
|
||||
#include <rsvcClient.h>
|
||||
#include <rsvcSpec.h>
|
||||
|
||||
extern "C" RSVCAPI cdevService * newRnsService (char* name, cdevSystem* system);
|
||||
|
||||
class rnsMonitorObj;
|
||||
class rnsRequestObject;
|
||||
|
||||
class rnsService: public cdevService
|
||||
{
|
||||
public:
|
||||
// cornstructor
|
||||
rnsService (char* name, cdevSystem& system = cdevSystem::defaultSystem ());
|
||||
|
||||
int getFd (int * &fd, int &numFd);
|
||||
// PURPOSE: return channel access network file descriptors
|
||||
// REQUIRE: callers provide pointer only and don't free memory
|
||||
// PROMISE: numFd will be real number of file descriptors of the
|
||||
// channel access client. return 0: always
|
||||
|
||||
int flush (void);
|
||||
// PURPOSE: flush network requests
|
||||
// REQUIRE: nothing
|
||||
// PROMISE: return CDEV_SUCCESS: success
|
||||
|
||||
int poll (void);
|
||||
// PURPOSE: polling method
|
||||
// REQUIRE: nothing
|
||||
// PROMISE: return CDEV_SUCCESS: success. Else error
|
||||
|
||||
int pend (int fd = -1);
|
||||
// PURPOSE: handle network pending
|
||||
// REQUIRE: nothing
|
||||
// PROMISE: return CDEV_SUCCESS: success, else error
|
||||
|
||||
int pend (double seconds, int fd = -1);
|
||||
// PURPOSE: handle network pending for 'seconds'
|
||||
// REQUIRE: nothing
|
||||
// PROMISE: return 0: success. return CDEV_TIMEOUT for timeout
|
||||
|
||||
int getRequestObject (char *deviceName, char *msg,
|
||||
cdevRequestObject * &req);
|
||||
// PURPOSE: return a rnsRequestObject (called from attachPtr function
|
||||
// of cdevRequestObject class)
|
||||
// REQUIRE: right pair of deviceName and msg.
|
||||
// PROMISE: a rnsRequestObject
|
||||
|
||||
int getNameServer (cdevDevice* &rns);
|
||||
// PURPOSE: retrieve ca name server in case of missing DDL
|
||||
// REQUIRE: nothing
|
||||
// PROMISE:
|
||||
|
||||
int monitorsRestarted (void);
|
||||
// PURPOSE: check whether all monitors have been restarted or not
|
||||
// REQUIRE: nothing
|
||||
// PROMISE: 1: yes, 0: no
|
||||
|
||||
int reconnect (void);
|
||||
// PURPOSE: reconnect to name server
|
||||
// REQUIRE: nothing
|
||||
// PROMISE: CDEV_SUCCESS on sucessful connection
|
||||
|
||||
const char* className (void) const {return "rnsService";}
|
||||
|
||||
protected:
|
||||
|
||||
// deny direct access to destructor
|
||||
~rnsService (void);
|
||||
|
||||
// add a monitor object
|
||||
int addMonitorObject (rnsMonitorObj* obj);
|
||||
// remove a monitor object
|
||||
int removeMonitorObject (rnsMonitorObj* obj);
|
||||
// check whether this callback is in the list
|
||||
rnsMonitorObj* hasCallback (cdevCallback& cbk);
|
||||
|
||||
// server disconnection callback
|
||||
static void discCallback (int status, void* arg, rsvcData* data);
|
||||
|
||||
private:
|
||||
rsvcClient client_;
|
||||
int *fds_;
|
||||
int numFds_;
|
||||
|
||||
// list of monitor object
|
||||
cdevSlist monobjs_;
|
||||
|
||||
// all tags needed for this service
|
||||
static char* tags_[];
|
||||
|
||||
// number of tags needed for this service
|
||||
static int numtags_;
|
||||
|
||||
// friend class
|
||||
friend class rnsRequestObject;
|
||||
};
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user