467 lines
16 KiB
C++
467 lines
16 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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:
|
|
// cdevSystem class
|
|
//
|
|
// Author: Jie Chen & Chip Watson
|
|
//
|
|
// Revision History:
|
|
// cdevSystem.h,v
|
|
// Revision 1.18 1998/02/13 14:23:06 chen
|
|
// add fall through service behaviour
|
|
//
|
|
// Revision 1.17 1998/02/10 18:05:47 chen
|
|
// add add/removeTimer to the system
|
|
//
|
|
// Revision 1.16 1997/12/12 16:39:42 chen
|
|
// add fix for VMS
|
|
//
|
|
// Revision 1.15 1997/08/27 18:23:33 chen
|
|
// Change error reporting to site specific scheme
|
|
//
|
|
// Revision 1.14 1997/08/07 13:36:33 akers
|
|
// Converted CDEV_MAJOR_VERSION and CDEV_MINOR_VERSION to strings to support adding minor revision numbers
|
|
//
|
|
// Revision 1.13 1997/03/25 22:24:43 akers
|
|
// Development in support of a new cdevDirectory
|
|
//
|
|
// Revision 1.12 1997/03/03 17:35:47 chen
|
|
// add buffering to channel access connection
|
|
//
|
|
// Revision 1.10 1997/01/29 17:39:38 akers
|
|
// Removed assertion from cdevSystem
|
|
//
|
|
// Revision 1.9 1996/11/21 17:03:34 akers
|
|
// Ongoing Developement of CDEV 1.5
|
|
//
|
|
// Revision 1.8 1996/09/20 12:24:58 akers
|
|
// Changes added for Release 1.4
|
|
//
|
|
// Revision 1.7 1996/04/05 22:02:24 chen
|
|
// fix static enum problem with gcc
|
|
//
|
|
// Revision 1.6 1996/03/27 16:03:10 akers
|
|
// Added CDEV_MAJOR_VERSION and CDEV_MINOR_VERSION to the cdevSystem object
|
|
//
|
|
// Revision 1.5 1996/03/22 17:57:00 chen
|
|
// add cdevFdChangedCallback
|
|
//
|
|
// Revision 1.4 1995/10/05 18:40:45 chen
|
|
// Move destructor to public, static needs it
|
|
//
|
|
// Revision 1.3 1995/07/05 18:45:41 chen
|
|
// allow access to devices etc...
|
|
//
|
|
// Revision 1.2 1995/06/30 16:06:26 chen
|
|
// remove all unnecessary files and use a genric list and hash
|
|
//
|
|
// Revision 1.1.1.1 1995/06/16 17:14:08 epics
|
|
// initial import of cdev
|
|
//
|
|
//
|
|
#ifndef _CDEV_SYSTEM_H
|
|
#define _CDEV_SYSTEM_H
|
|
|
|
#include <cdevSpec.h>
|
|
#include <cdevVersion.h>
|
|
#include <cdevSlist.h>
|
|
#include <cdevStrHash.h>
|
|
#include <cdevSystemBase.h>
|
|
#include <cdevTimerQueue.h>
|
|
|
|
#ifdef __VMS
|
|
extern "C" {
|
|
char* strdup (char *s);
|
|
char* mkstemp (char *s);
|
|
int htonl (int a);
|
|
int ntohl (int a);
|
|
};
|
|
#endif
|
|
|
|
class cdevService;
|
|
class cdevDevice;
|
|
class cdevRequestObject;
|
|
class cdevErrReqObject;
|
|
class cdevDirectory;
|
|
class cdevGroup;
|
|
class cdevExecGroup;
|
|
class cdevSvcFinder;
|
|
class cdevTranObj;
|
|
class cdevCallback;
|
|
class cdevErrSvc;
|
|
class cdevConfigFinder;
|
|
|
|
// maximum number of groups inside a system
|
|
const int MAX_NUM_GROUPS = 5;
|
|
|
|
// file descriptor changed callback
|
|
// opened = 1, newly opend fd, opened = 0, closed fd
|
|
typedef void (*cdevFdChangedCallback) (int fd, int opened,
|
|
void *arg);
|
|
|
|
// arbitrary user fd callback (user let cdev to minitor his/her's fd)
|
|
// opened = 1, ok, opened = 0, fd is bad fd
|
|
// user should return 0: for success reading, -1: for failure
|
|
typedef int (*cdevUserFdCallback) (int opened, int fd, void *arg);
|
|
|
|
// define user fd callback handler id
|
|
typedef long cdevUserFdCbkId;
|
|
|
|
|
|
class CDEV_CLASS_SPEC cdevSystem: public cdevSystemBase
|
|
{
|
|
public:
|
|
// ***************************************************************************
|
|
// * The CDEV_MAJOR_VERSION and CDEV_MINOR_VERSION variables are used to
|
|
// * identify the version of CDEV shared objects that should be used.
|
|
// ***************************************************************************
|
|
|
|
// WARNING: these two strings are deprecated in 1.7.x, and will be
|
|
// removed in 1.8, and replace with a single version string.
|
|
|
|
static const char *CDEV_MAJOR_VERSION;
|
|
static const char *CDEV_MINOR_VERSION;
|
|
|
|
//==============================================================
|
|
// Public interface for clients
|
|
//==============================================================
|
|
static cdevSystem& attachRef (char *name, char *prefix = 0);
|
|
static cdevSystem* attachPtr (char *name, char *prefix = 0);
|
|
// PURPOSE: cdevSystem creation factory
|
|
// REQUIRE: nothing
|
|
// PROMISE: return system reference or pointer
|
|
|
|
cdevDevice* getDevice (char *device);
|
|
// PURPOSE: create a cdevDevice
|
|
// REQUIRE: device != 0
|
|
// PROMISE: return a pointer to a cdevDevice
|
|
|
|
char *name (void) const;
|
|
// PURPOSE: return name of this system
|
|
// REQUIRE: callers don't free memory
|
|
// PROMISE: name of this system
|
|
|
|
char *prefix (void) const;
|
|
// PURPOSE: return prefix of this system
|
|
// REQUIRE: callers don't free memory
|
|
// PROMISE: prefix of this syste,
|
|
|
|
void prefix (char *pre);
|
|
// PURPOSE: set prefix to this system
|
|
// REQUIRE: pre != 0
|
|
// PROMISE: old prefix will be overwritten by new one
|
|
|
|
virtual int flush (void);
|
|
// PURPOSE: flush all network request to all services
|
|
// REQUIRE: nothing
|
|
// PROMISE: return CDEV_SUCCESS
|
|
|
|
virtual int poll (void);
|
|
// PURPOSE: poll all network services
|
|
// REQUIRE: nothing
|
|
// PROMISE: return CDEV_SUCCESS
|
|
|
|
virtual int pend (int fd = -1);
|
|
// PURPOSE: pend all network services and dispatch IO event to right services
|
|
// REQUIRE: nothing
|
|
// PROMISE: return CDEV_SUCCESS
|
|
|
|
virtual int pend (double seconds, int fd = -1);
|
|
// PURPOSE: pend all network services for 'seconds' time long.
|
|
// Dispatch IO event to right services
|
|
// REQUIRE: nothing
|
|
// PROMISE: return CDEV_SUCCESS or CDEV_TIMEOUT
|
|
|
|
static cdevSystem &defaultSystem (void);
|
|
// PURPOSE: Caller access to default system which is created automatically
|
|
// REQUIRE: nothing
|
|
// PROMISE: return the same system everytime one calls this
|
|
|
|
void finalize (void);
|
|
// PURPOSE: clean up all system resources
|
|
// REQUIRE: last routine to call before quitting
|
|
// PROMISE: nothing
|
|
|
|
int getFd (int fd[], int &numFD);
|
|
// PURPOSE: provide file descriptors to other system such as X window
|
|
// REQUIRE: user provide big enough integer buffer and buffer size
|
|
// PROMISE: numFD is real number of fds of success return CDEV_SUCCESS.
|
|
// return CDEV_INVALIDARG: not big enoght buffer
|
|
|
|
int addFdChangedCallback (cdevFdChangedCallback cbk, void* arg);
|
|
// PURPOSE: provide file descriptor callback mechanism
|
|
// REQUIRE: none
|
|
// PROMISE: if lower cdevServices provide system any notification of
|
|
// fd changes, the system will call all registered callbacks
|
|
|
|
int addUserFdCallback (int fd, cdevUserFdCallback cbk, void* arg,
|
|
cdevUserFdCbkId& id);
|
|
// PURPOSE: add user fd to system fd list, when there is something
|
|
// to be read at this fd, the user callback will be executed
|
|
// REQUIRE: none
|
|
// PROMISE: if fd is already inside the managed fd list, returns
|
|
// CDEV_INVALIDARG. if fd is a bad fd, returns CDEV_IOFAILED.
|
|
// CDEV_SUCCESS and valid id will denote a success
|
|
|
|
int removeUserFdCallback (cdevUserFdCbkId id);
|
|
// PURPOSE: remove a user register fd callback with callback id
|
|
// REQUIRE: none
|
|
// PROMISE: return CDEV_NOTFOUND, if id is not found. return CDEV_SUCCESS
|
|
// if id has been removed (system will close associated fd if it
|
|
// is a not bad fd)
|
|
|
|
int addTimer (cdevTimerHandler* handler,
|
|
const void* arg,
|
|
double delay, double interval = 0.0);
|
|
// PURPOSE: register a <cdevTimerHandler> 'handler' that will expire
|
|
// after delay amount of seconds. If it expires then <arg> is
|
|
// passed in the <timerCallback> function of handler. If
|
|
// interval != 0.0, then this timer becomes a repetitive timer
|
|
// with timer interval 'interval'.
|
|
// REQUIRE: handler must have a real timerCallback function
|
|
// PROMISE: A unique id will be returned. Callers can use this id
|
|
// to cancel timer before it expires.
|
|
|
|
int removeTimer (cdevTimerHandler* handler);
|
|
// PURPOSE: remove timers associated with a <cdevTimerHandler> 'handler'
|
|
// REQUIRE: none
|
|
// PROMISE: return CDEV_SUCCESS if all timers are removed. return CDEV_ERROR
|
|
// if there is no timer associated with this handler
|
|
|
|
int removeTimer (int timerid);
|
|
// PURPOSE: remove a timer with timer id 'timerid'
|
|
// REQUIRE: none
|
|
// PROMISE: return CDEV_SUCCESS if the timer is removed. return CDEV_ERROR
|
|
// if this timer is not registered.
|
|
|
|
void enableDefaultSvc (void);
|
|
void disableDefaultSvc (void);
|
|
// PURPOSE: enable/disable using default service if a device msg pair cannot
|
|
// match to any services
|
|
// REQUIRE: none
|
|
// PROMISE:
|
|
|
|
int defaultSvc (void) const;
|
|
// PURPOSE: check whether a default service in used if a device msg pair
|
|
// cannot match any services
|
|
// REQUIRE: none
|
|
// PROMISE: return 1 true. return 0 false
|
|
|
|
//===================================================================
|
|
// Public interface for internal implementation use
|
|
//===================================================================
|
|
virtual int registerService (cdevService *service);
|
|
// PURPOSE: register a service to the system
|
|
// REQUIRE: service != 0
|
|
// PROMISE: service only be registered once
|
|
|
|
virtual int removeService (cdevService *service);
|
|
// PURPOSE: remove this service from the system
|
|
// REQUIRE: service != 0
|
|
// PROMISE: service will be removed, but service is sitll valid
|
|
|
|
virtual int serviceCreated (char *serviceName);
|
|
// PURPOSE: check a service inside the system by name
|
|
// REQUIRE: serviceName != 0
|
|
// PROMISE: return 1: found, 0: not found
|
|
|
|
cdevService *service (char *serviceName);
|
|
// PURPOSE: return a service pointer inside system by name
|
|
// REQUIRE: serviceName != 0
|
|
// PROMISE: return cdevService* != 0 on success, return 0: failure
|
|
|
|
cdevService *loadService (char *serviceName);
|
|
// PURPOSE: load a new service by service name (shared library)
|
|
// REQUIRE: serviceName != 0
|
|
// PROMISE: return cdevService* != 0 on success, return 0: failure
|
|
|
|
virtual int suspendService (cdevService *service);
|
|
// PURPOSE: temprarily suspend service
|
|
// REQUIRE: nothing
|
|
// PROMISE: not implemented yet
|
|
|
|
virtual int resumeService (cdevService *service);
|
|
// PURPOSE: resume a suspended service
|
|
// REQUIRE: nothing
|
|
// PROMISE: not implemented yet
|
|
|
|
int registerDevice (cdevDevice *device);
|
|
// PURPOSE: register a cdevDevice to the system
|
|
// REQUIRE: device != 0
|
|
// PROMISE: device will be registered once, CDEV_SUCCESS: success.
|
|
// CDEV_ERROR: already here
|
|
|
|
int removeDevice (cdevDevice *);
|
|
// PURPOSE: remove a device from the system
|
|
// REQUIRE: device != 0
|
|
// PROMISE: return CDEV_SUCCESS: rmoval success.
|
|
// return CDEV_ERROR: not here
|
|
|
|
int deviceCreated (char *deviceName);
|
|
// PURPOSE: check a device created in the system by name
|
|
// REQUIRE: deviceName != 0
|
|
// PROMISE: return 1: device is here, return 0: not here
|
|
|
|
cdevDevice *device (char *deviceName);
|
|
// PURPOSE: return a device in the system by name
|
|
// REQUIRE: deviceName != 0
|
|
// PROMISE: return device !=0 on success, return 0: failure
|
|
|
|
virtual int getRequestObject (char *deviceName,
|
|
char *msg,
|
|
cdevRequestObject * &req);
|
|
// PURPOSE: get a cdevRequestObject from system by devicename and message
|
|
// REQUIRE: deviceName != 0 and msg != 0
|
|
// PROMISE: return CDEV_SUCCESS: success.
|
|
// return CDEV_ERROR: failure
|
|
|
|
int registerGroup (cdevGroup *grp);
|
|
// PURPOSE: register a group into the system
|
|
// REQUIRE: grp != 0
|
|
// PROMISE: return CDEV_SUCCESS: success, CDEV_ERROR: already here
|
|
|
|
int removeGroup (cdevGroup *grp);
|
|
// PURPOSE: remove a group from the system
|
|
// REQUIRE: grp != 0
|
|
// PROMISE: return CDEV_SUCCESS: removal success.
|
|
// return CDEV_ERROR: not here. grp is still valid.
|
|
|
|
int registerActiveGroup (cdevGroup *grp);
|
|
// PURPOSE: register an active group (group stared)
|
|
// REQUIRE: grp != 0
|
|
// PROMISE: return CDEV_SUCCESS: success,
|
|
// CDEV_ERROR: already here
|
|
|
|
int removeActiveGroup (cdevGroup *grp);
|
|
// PURPOSE: remove an active group
|
|
// REQUIRE: grp != 0
|
|
// PROMISE: return CDEV_SUCCESS: success.
|
|
// return CDEV_ERROR: not here. grp is still valid
|
|
|
|
int activeGroups (cdevGroup **grps, int& numGroups);
|
|
// PURPOSE: return active groups inside the system
|
|
// REQUIRE: callers provide memory for grps (eg. grps = new cdevGroup*[5])
|
|
// or cdevGroup grps[5]. numGroups is the buffer size of grps.
|
|
// callers don't free grps[i] which is a pointer to internal rep.
|
|
// PROMISE: numGrps is the real number of active groups
|
|
|
|
int activeGroups (void) const;
|
|
// PURPOSE: check whether there are any active groups
|
|
// REQUIRE: nothing
|
|
// PROMISE: 1: yes, 0: no
|
|
|
|
cdevDirectory& nameServer (void);
|
|
// PURPOSE: default name server
|
|
// REQUIRE: nothing
|
|
// PROMISE: always here
|
|
|
|
cdevRequestObject *errorRequestObject (void);
|
|
// PURPOSE: return default error request object in case of error
|
|
// REQUIRE: nothing
|
|
// PROMISE: return error request object
|
|
|
|
void errorRequestObject (cdevRequestObject *obj);
|
|
// PURPOSE: set default error request object in case of error
|
|
// REQUIRE: nothing
|
|
// PROMISE: default error request object will be set
|
|
|
|
virtual ~cdevSystem (void);
|
|
|
|
protected:
|
|
// constructor and destructor
|
|
cdevSystem (char *systemName, char *prefix = 0);
|
|
|
|
// redefine attach/detach file descriptor to notify callback if there
|
|
// any of them
|
|
virtual int attachReadFd (int fd);
|
|
virtual int detachReadFd (int fd);
|
|
|
|
// setup the read mask in preparation for pend operation.
|
|
void setupMask ( void );
|
|
|
|
// free all memory
|
|
void freeMemory (void);
|
|
// interface to system collection
|
|
static int remove (cdevSystem *);
|
|
|
|
// handle network I/O events
|
|
virtual int handleEvents (cdevTimeValue* tv);
|
|
|
|
// calculate time out according to user request maximum timeout
|
|
// and timer queue earliest timeout
|
|
// returned pointer is a pointer to a static value
|
|
cdevTimeValue* calculateTimeOut (cdevTimeValue* maxtimeout);
|
|
|
|
// notify lower level service object
|
|
virtual void notifyService (int handle);
|
|
// get individul service from file descriptor
|
|
cdevService *getService (int handle);
|
|
|
|
private:
|
|
// data area
|
|
cdevSlist serviceList_;
|
|
// hash table keep track all devices which are keyed by device name
|
|
cdevStrHash deviceList_;
|
|
// group list inside the system
|
|
cdevSlist groupList_;
|
|
// active group list inside the system
|
|
cdevSlist activeGroupList_;
|
|
// system list
|
|
static cdevSlist& systemList_ (void);
|
|
// flag to denote there are some active groups
|
|
int activeGrps_;
|
|
// this system name
|
|
char *systemName_;
|
|
// prefix name for this system
|
|
char *prefix_;
|
|
// default name server, cdevDirectory for now
|
|
cdevDirectory *ns_;
|
|
// cdevService name binding mechanism
|
|
cdevSvcFinder *svcFinder_;
|
|
// cdev site configuraton loader
|
|
cdevConfigFinder *configFinder_;
|
|
// Reference counting
|
|
int refCount_;
|
|
// callback list for fdChangedCallback
|
|
cdevSlist fdCbkList_;
|
|
cdevSlist fdCbkArgList_;
|
|
// timer queue
|
|
cdevTimerQueue timerQueue_;
|
|
// fall through to a default service or not if no service is found
|
|
int defaultSvc_;
|
|
|
|
//====================================================
|
|
// The followings are for linked editor.
|
|
// Try to trick the link editor to load those symbols
|
|
// which otherwise will not be exported to library
|
|
//====================================================
|
|
// default cdevServiceError handler object
|
|
cdevService *errSvcObj_;
|
|
// touch cdevTranObj class and alot of more
|
|
cdevTranObj *defXobj_;
|
|
// touch cdevCallback class
|
|
cdevCallback *defCallbackObj_;
|
|
// default requestobject error handle object
|
|
cdevRequestObject *errObj_;
|
|
// an empty cdevExecGroup object
|
|
cdevExecGroup* egroup_;
|
|
//===================================================
|
|
// Deny access since memeber-wise copy will not work
|
|
// since this system is actually a memory manager
|
|
//===================================================
|
|
cdevSystem (const cdevSystem &);
|
|
cdevSystem& operator = (const cdevSystem &);
|
|
// friend class declaration
|
|
friend class cdevService;
|
|
friend class cdevErrReqObject;
|
|
};
|
|
|
|
#endif
|