cdev-1.7.2n
This commit is contained in:
403
extensions/cdevGenericServer/cdevServer/cdevServerTools.cc
Executable file
403
extensions/cdevGenericServer/cdevServer/cdevServerTools.cc
Executable file
@@ -0,0 +1,403 @@
|
||||
#include "cdevServerTools.h"
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// cdevSimpleTimer::cdevSimpleTimer :
|
||||
// Constructor.
|
||||
// ****************************************************************************
|
||||
cdevSimpleTimer::cdevSimpleTimer ( cdevReactor & Reactor, double Rate)
|
||||
{
|
||||
setTimeoutRate(Rate);
|
||||
if(Reactor.registerTimer (this) == -1)
|
||||
{
|
||||
outputError ( CDEV_SEVERITY_SEVERE, "cdevSimpleTimer",
|
||||
"Unable to register timer with cdevReactor");
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// cdevSimpleTimer::~cdevSimpleTimer :
|
||||
// Destructor.
|
||||
// ****************************************************************************
|
||||
cdevSimpleTimer::~cdevSimpleTimer ( void )
|
||||
{
|
||||
if(reactor) reactor->extractHandler(this);
|
||||
handleClose();
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// cdevSimpleTimer::handle_timeout :
|
||||
// Called when the timer expires.
|
||||
// ****************************************************************************
|
||||
int cdevSimpleTimer::handleTimeout(void)
|
||||
{
|
||||
return execute();
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerManager::cdevNameServerManager :
|
||||
// * This method will read the CDEV_NAME_SERVER environment variable to
|
||||
// * obtain a list of one or more cdev name servers that should be notified
|
||||
// * that this server is operational. The class will create a
|
||||
// * cdevNameServerHandler event handler to manage the connection to each of
|
||||
// * the specified name servers. If a connection is lost to one of the
|
||||
// * name servers, the cdevNameServerManager will attempt periodically to
|
||||
// * reconnect to the specific name server.
|
||||
// *****************************************************************************
|
||||
cdevNameServerManager::cdevNameServerManager ( cdevReactor & Reactor,
|
||||
char * DomainName,
|
||||
char * ServerName,
|
||||
unsigned short ServerPort )
|
||||
: domainName(strdup(DomainName)),
|
||||
serverName(strdup(ServerName)),
|
||||
serverPort(ServerPort),
|
||||
nameServerList(NULL),
|
||||
nameServerHandlers(NULL),
|
||||
nameServerCnt(0)
|
||||
{
|
||||
// *********************************************************************
|
||||
// * Prior to establishing any connections, the class must first install
|
||||
// * all of the necessary data into the serverInfo and updateInfo
|
||||
// * objects.
|
||||
// *********************************************************************
|
||||
char * userName = getenv("USER");
|
||||
char hostname[255];
|
||||
struct hostent * hostPtr;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday (&tv);
|
||||
gethostname(hostname, 255);
|
||||
hostPtr = gethostbyname(hostname);
|
||||
|
||||
serverInfo.insert ("name", serverName);
|
||||
serverInfo.insert ("domain", domainName);
|
||||
serverInfo.insert ("host", (char *)hostPtr->h_name);
|
||||
serverInfo.insert ("owner", userName?userName:(char *)"UNKNOWN");
|
||||
serverInfo.insert ("time", (long)tv.tv_sec);
|
||||
serverInfo.insert ("port", (long)serverPort);
|
||||
serverInfo.insert ("pid", getpid ());
|
||||
updateInfo.insert ("name", serverName);
|
||||
updateInfo.insert ("domain", domainName);
|
||||
|
||||
// *********************************************************************
|
||||
// * First obtain a list of name servers from the CDEV_NAME_SERVER
|
||||
// * environment variable. If this list is empty, then report an
|
||||
// * error once and then never call the handler again.
|
||||
// *********************************************************************
|
||||
char * nsList = getenv("CDEV_NAME_SERVER");
|
||||
int idx;
|
||||
int length;
|
||||
|
||||
if(nsList!=NULL)
|
||||
{
|
||||
char * nsPtr = nsList;
|
||||
char * endPtr = nsList;
|
||||
|
||||
// *************************************************************
|
||||
// * Determine the number of name servers that have been
|
||||
// * defined in the CDEV_NAME_SERVER environment variable.
|
||||
// *************************************************************
|
||||
while(*nsPtr==':' && *nsPtr!=0) nsPtr++;
|
||||
if(*nsPtr!=0)
|
||||
{
|
||||
nameServerCnt = 1;
|
||||
while(nsPtr!=NULL && *nsPtr!=0)
|
||||
{
|
||||
if((nsPtr = strchr(nsPtr, ':'))!=NULL)
|
||||
{
|
||||
while(*(++nsPtr)==':' && *nsPtr!=0);
|
||||
if(*nsPtr!=0) nameServerCnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// * Copy each of the defined cdev name server host names into
|
||||
// * the nameServerList.
|
||||
// *************************************************************
|
||||
if(nameServerCnt>0)
|
||||
{
|
||||
nameServerList = new char *[nameServerCnt];
|
||||
nameServerHandlers = new cdevNameServerHandler *[nameServerCnt];
|
||||
|
||||
for(nsPtr = nsList, idx=0; idx<nameServerCnt && *nsPtr!=0; idx++)
|
||||
{
|
||||
while(*nsPtr==':' && *nsPtr!=0) nsPtr++;
|
||||
for(endPtr=nsPtr; *endPtr && *endPtr!=':'; endPtr++);
|
||||
length = endPtr-nsPtr;
|
||||
|
||||
nameServerList[idx] = new char[length+1];
|
||||
strncpy(nameServerList[idx], nsPtr, length);
|
||||
nameServerList[idx][length] = 0;
|
||||
nsPtr = endPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * If no cdev name servers have been defined in the cdev name server
|
||||
// * list, print a warning message.
|
||||
// ********************************************************************
|
||||
if(nameServerCnt<=0)
|
||||
{
|
||||
outputError(CDEV_SEVERITY_WARN, "CDEV Name Server Manager",
|
||||
"\n%s\n%s\n%s",
|
||||
" => No name servers have been specified in the CDEV_NAME_SERVER",
|
||||
" => environment variable.",
|
||||
" => This server WILL NOT be registered with any name servers...");
|
||||
}
|
||||
// *********************************************************************
|
||||
// * Otherwise, set all of the cdevNameServerHandler pointers to NULL
|
||||
// * so that they will be connected when the execute timeout method
|
||||
// * is called.
|
||||
// *********************************************************************
|
||||
else {
|
||||
for(idx=0; idx<nameServerCnt; idx++)
|
||||
{
|
||||
nameServerHandlers[idx] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// * Register this class with the cdevReactor so that it will be called
|
||||
// * every thirty seconds. If any of the cdevNameServerHandlers have
|
||||
// * become disconnected, it will attempt to reestablish the connection
|
||||
// * at that time.
|
||||
// *********************************************************************
|
||||
setTimeoutRate(15.0);
|
||||
Reactor.registerTimer(this);
|
||||
handleTimeout();
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerManager::~cdevNameServerManager :
|
||||
// * This is the destructor for the cdevNameServerManager class. When called
|
||||
// * it will remove and delete any cdevNameServerHandlers that have been
|
||||
// * registered with the cdevReactor.
|
||||
// *****************************************************************************
|
||||
cdevNameServerManager::~cdevNameServerManager ( void )
|
||||
{
|
||||
int idx;
|
||||
|
||||
for(idx = 0; idx<nameServerCnt; idx++)
|
||||
{
|
||||
if(nameServerHandlers[idx]!=0) delete nameServerHandlers[idx];
|
||||
if(nameServerList[idx]!=NULL) delete nameServerList[idx];
|
||||
}
|
||||
if(nameServerList!=NULL) delete nameServerList;
|
||||
if(nameServerHandlers!=NULL) delete nameServerHandlers;
|
||||
if(domainName!=NULL) delete domainName;
|
||||
if(serverName!=NULL) delete serverName;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerManager::handleTimeout :
|
||||
// * This method will be called every thirty seconds to make sure that all
|
||||
// * connections to the cdev name servers are established. If a
|
||||
// * cdevNameServerHandler has become disconnected, this method will attempt
|
||||
// * to reconnect to the specified handler.
|
||||
// *****************************************************************************
|
||||
int cdevNameServerManager::handleTimeout ( void )
|
||||
{
|
||||
int idx;
|
||||
for(idx=0; idx<nameServerCnt; idx++)
|
||||
{
|
||||
if(nameServerHandlers[idx]==NULL &&
|
||||
nameServerList[idx]!=NULL)
|
||||
{
|
||||
int error = 0;
|
||||
rsvcClient * client = new rsvcClient;
|
||||
rsvcUdpClient * udpClient = new rsvcUdpClient;
|
||||
if(client->connect(nameServerList[idx], RSVC_SERVER_PORT, 2.0)!=RSVC_SUCCESS)
|
||||
{
|
||||
outputError ( CDEV_SEVERITY_ERROR, "CDEV Name Server Manager",
|
||||
"Failed to connect to name server on host %s",
|
||||
nameServerList[idx]);
|
||||
error = -1;
|
||||
}
|
||||
else if(udpClient->connect(nameServerList[idx], RSVC_SERVER_PORT+1024)!=RSVC_SUCCESS)
|
||||
{
|
||||
outputError ( CDEV_SEVERITY_ERROR, "CDEV Name Server Manager",
|
||||
"Failed to open UDP port to name server on host %s",
|
||||
nameServerList[idx]);
|
||||
error = -1;
|
||||
}
|
||||
else if(client->insertValue ("cdevServers", serverInfo, rsvcCallback, nameServerList[idx], 1)!=RSVC_SUCCESS)
|
||||
{
|
||||
outputError ( CDEV_SEVERITY_ERROR, "CDEV Name Server Manager",
|
||||
"Error transmitting to name server on host %s",
|
||||
nameServerList[idx]);
|
||||
error = -1;
|
||||
}
|
||||
|
||||
if(!error) nameServerHandlers[idx] = new cdevNameServerHandler(*this, *reactor, idx, client, udpClient);
|
||||
else {
|
||||
client->disconnect();
|
||||
udpClient->disconnect();
|
||||
delete client;
|
||||
delete udpClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerManager::unregisterHandler:
|
||||
// * This method is called whenever a cdevNameServerHandler needs to
|
||||
// * unregister itself from the cdevNameServerManager. The handlers index
|
||||
// * will be set to 0 and the connection will be reestablished the next time
|
||||
// * the handleTimeout method is called.
|
||||
// *****************************************************************************
|
||||
void cdevNameServerManager::unregisterHandler ( size_t index )
|
||||
{
|
||||
if(index < nameServerCnt) nameServerHandlers[index] = NULL;
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerManager::rsvcCallback :
|
||||
// * This is the method that is called when the register server method
|
||||
// * is executed.
|
||||
// *****************************************************************************
|
||||
void cdevNameServerManager::rsvcCallback (int status, void* arg, rsvcData* /* data */)
|
||||
{
|
||||
char * nameServer = (char *)arg;
|
||||
|
||||
if (status != RSVC_SUCCESS)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
fprintf(stderr, "CDEV Name Server Manager Error: %s %s\n",
|
||||
"Failed to register with name server on host",
|
||||
nameServer?nameServer:"UNKNOWN");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerHandler::cdevNameServerHandler :
|
||||
// * This is the constructor for the cdevNameServerHandler class. It is
|
||||
// * called by the cdevNameServerManager when a new cdevNameServerHandler
|
||||
// * must be created to communicate with a name server. The connected
|
||||
// * rsvcClient and rsvcUdpClient objects are provided to the class.
|
||||
// ******************************************************************************
|
||||
cdevNameServerHandler::cdevNameServerHandler ( cdevNameServerManager & Manager,
|
||||
cdevReactor & Reactor,
|
||||
int index,
|
||||
rsvcClient * tcpClient,
|
||||
rsvcUdpClient * udpClient )
|
||||
: nameServerTCP(tcpClient), nameServerUDP(udpClient),
|
||||
nameServerIndex(index), nameServerManager(Manager)
|
||||
{
|
||||
setTimeoutRate(5.0);
|
||||
setMask(WRITE_MASK);
|
||||
Reactor.registerHandler(this, WRITE_MASK);
|
||||
Reactor.registerTimer (this);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerHandler::~cdevNameServerHandler :
|
||||
// * This is the destructor for the class. this method is responsible for
|
||||
// * disconnecting and closing the tcp and udp client connections and
|
||||
// * sending notification to the cdevNameServerManager that it is
|
||||
// * terminating.
|
||||
// *****************************************************************************
|
||||
cdevNameServerHandler::~cdevNameServerHandler ( void )
|
||||
{
|
||||
nameServerTCP->disconnect();
|
||||
nameServerUDP->disconnect();
|
||||
delete nameServerTCP;
|
||||
delete nameServerUDP;
|
||||
if(reactor) reactor->extractHandler(this);
|
||||
nameServerManager.unregisterHandler(nameServerIndex);
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerHandler::handleInput :
|
||||
// * This method is called whenever data is ready to be read from the
|
||||
// * nameServerTCP rsvcClient connection.
|
||||
// *****************************************************************************
|
||||
int cdevNameServerHandler::handleInput ( void )
|
||||
{
|
||||
return (nameServerTCP->pendIO()==RSVC_IOERROR)?-1:0;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerHandler::handleOutput :
|
||||
// * This method is called whenever data is ready to be written to the
|
||||
// * nameServerTCP rsvcClient connection.
|
||||
// *****************************************************************************
|
||||
int cdevNameServerHandler::handleOutput ( void )
|
||||
{
|
||||
setMask(READ_MASK);
|
||||
return (nameServerTCP->pendIO()==RSVC_IOERROR)?-1:0;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerHandler::handleTimeout :
|
||||
// * This method is called every five seconds to allow the object to emit
|
||||
// * a UDP packet to the name server to notify it that the server is alive.
|
||||
// *****************************************************************************
|
||||
int cdevNameServerHandler::handleTimeout ( void )
|
||||
{
|
||||
if(nameServerUDP->update(*nameServerManager.getUpdateInfo())!=RSVC_SUCCESS)
|
||||
{
|
||||
outputError(CDEV_SEVERITY_ERROR, "CDEV Name Server Handler",
|
||||
"Failed to update name server on host %s",
|
||||
nameServerManager.getHostName(nameServerIndex));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// * cdevNameServerHandler::getHandle :
|
||||
// * This method allows the caller to obtain the file handle that is being
|
||||
// * used by the nameServerTCP rsvcClient connection. This handle is used
|
||||
// * by the cdevReactor to detect when an event has occured.
|
||||
// *****************************************************************************
|
||||
int cdevNameServerHandler::getHandle ( void ) const
|
||||
{
|
||||
return nameServerTCP->getFd();
|
||||
}
|
||||
|
||||
|
||||
#ifndef DONT_SUPPORT_CDEV_CALLS
|
||||
// *********************************************************************
|
||||
// * cdevSystemHandler::cdevSystemHandler :
|
||||
// * This is the constructor for the cdevSystemHandler object.
|
||||
// *********************************************************************
|
||||
cdevSystemHandler::cdevSystemHandler (cdevReactor & Reactor,
|
||||
double pollRate,
|
||||
cdevSystem & System)
|
||||
: cdevSimpleTimer(Reactor, pollRate), system(System)
|
||||
{
|
||||
execute();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DONT_SUPPORT_CDEV_CALLS
|
||||
// *********************************************************************
|
||||
// * cdevSystemHandler::~cdevSystemHandler :
|
||||
// * This is the destructor for the cdevSystemHandler object.
|
||||
// *********************************************************************
|
||||
cdevSystemHandler::~cdevSystemHandler (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DONT_SUPPORT_CDEV_CALLS
|
||||
// *********************************************************************
|
||||
// * cdevSystemHandler::execute :
|
||||
// * This is the method that is executed when the specified timer
|
||||
// * expires.
|
||||
// *********************************************************************
|
||||
int cdevSystemHandler::execute (void)
|
||||
{
|
||||
system.poll();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user