//----------------------------------------------------------------------------- // 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 #include #include #include #include #include #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 'handler' that will expire // after delay amount of seconds. If it expires then is // passed in the 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 '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