dfMgr =>fdManager

This commit is contained in:
Jeff Hill
1996-08-13 22:48:25 +00:00
parent 13c03c4cde
commit 2ec12266ad
6 changed files with 477 additions and 48 deletions

View File

@@ -18,7 +18,7 @@ INC += memDebugLib.h
INC += tsDefs.h
INC += bucketLib.h
INC += pal.h
INC += fdMgr.h
INC += fdManager.h
INC += osiTime.h
INC += osiTimer.h
INC += macLib.h
@@ -42,7 +42,7 @@ SRCS.c += ../postfix.c
SRCS.c += ../realpath.c
SRCS.c += ../tsSubr.c
SRCS.c += ../assertUNIX.c
SRCS.c += ../fdMgr.cc
SRCS.c += ../fdManager.cc
SRCS.c += ../osiTimer.cc
SRCS.c += ../osiTimeOSD.cc
SRCS.c += ../macCore.c
@@ -67,7 +67,7 @@ LIBOBJS += postfix.o
LIBOBJS += realpath.o
LIBOBJS += tsSubr.o
LIBOBJS += assertUNIX.o
LIBOBJS += fdMgr.o
LIBOBJS += fdManager.o
LIBOBJS += osiTimer.o
LIBOBJS += osiTimeOSD.o
LIBOBJS += macCore.o

View File

@@ -66,14 +66,23 @@ include $(TOP)/config/RULES.Vx
clean::
@$(RM) errSymTbl.c envData.c
# In principle the simplified scripts in ../WIN32
# should work on all archs, but I decided to
# keep the "originals" for now. -kuk-
ifeq ($(HOST_ARCH),WIN32)
TOOLDIR=../WIN32
else
TOOLDIR=..
endif
envData.c: ../envDefs.h $(TOP)/config/CONFIG_ENV \
$(TOP)/config/CONFIG_SITE_ENV
../bldEnvData $(TOP)/config
$(TOOLDIR)/bldEnvData $(TOP)/config
errSymTbl.o: errSymTbl.c
$(COMPILE.c) -o $@ $<
errSymTbl.c: $(ERR_S_FILES)
@/bin/rm -f errSymTbl.c ;\
../makeStatTbl $(ERR_S_FILES) >errSymTbl.c
@$(RM) errSymTbl.c ;\
$(TOOLDIR)/makeStatTbl $(ERR_S_FILES) >errSymTbl.c

View File

@@ -2,18 +2,8 @@
//
// $Id$
//
// File descriptor management C++ class library
//
// $Log$
// Revision 1.3 1996/07/24 23:01:03 jhill
// use iter.remove()
//
// Revision 1.2 1996/07/09 23:02:05 jhill
// mark fd entry in limbo during delete
//
// Revision 1.1 1996/06/21 01:08:53 jhill
// add fdMgr.h fdMgr.cc
//
//
//
@@ -39,10 +29,10 @@
} //extern "C"
#endif // __GNUC__
#include <fdMgr.h>
#include <fdManager.h>
#include <osiTimer.h>
fdMgr fileDescriptorManager;
fdManager fileDescriptorManager;
inline int selectErrno()
{
@@ -50,9 +40,9 @@ inline int selectErrno()
}
//
// fdMgr::fdMgr()
// fdManager::fdManager()
//
fdMgr::fdMgr()
fdManager::fdManager()
{
FD_ZERO (&this->read);
FD_ZERO (&this->write);
@@ -63,9 +53,9 @@ fdMgr::fdMgr()
}
//
// fdMgr::~fdMgr()
// fdManager::~fdManager()
//
fdMgr::~fdMgr()
fdManager::~fdManager()
{
fdReg *pReg;
@@ -80,9 +70,9 @@ fdMgr::~fdMgr()
}
//
// fdMgr::process()
// fdManager::process()
//
void fdMgr::process (const osiTime &delay)
void fdManager::process (const osiTime &delay)
{
tsDLIter<fdReg> regIter(this->regList);
osiTime minDelay;
@@ -135,7 +125,7 @@ void fdMgr::process (const osiTime &delay)
}
else {
fprintf(stderr,
"fdMgr: select failed because \"%s\"\n",
"fdManager: select failed because \"%s\"\n",
strerror(selectErrno()));
}
}

View File

@@ -32,22 +32,23 @@
*
* History
* $Log$
* Revision 1.1 1996/06/21 01:08:54 jhill
* add fdMgr.h fdMgr.cc
*
*
*/
#ifndef fdMgrH_included
#define fdMgrH_included
#ifndef fdManagerH_included
#define fdManagerH_included
#include <tsDLList.h>
#include <osiTime.h>
#ifdef WIN32
#include <winsock.h>
#else
extern "C" {
# include <sys/types.h>
# include <sys/time.h>
} // extern "C"
#endif
#include <stdio.h>
@@ -59,7 +60,7 @@ enum fdRegState {fdrActive, fdrPending, fdrLimbo};
// file descriptor registration
//
class fdReg : public tsDLNode<fdReg> {
friend class fdMgr;
friend class fdManager;
public:
fdReg (const int fdIn, const fdRegType typ,
const unsigned onceOnly=0);
@@ -71,7 +72,7 @@ private:
//
// called when there is activity on the fd
// NOTES
// 1) the fdMgr will call this only once during the
// 1) the fdManager will call this only once during the
// lifetime of a fdReg object if the constructor
// specified "onceOnly"
//
@@ -79,7 +80,7 @@ private:
//
// Called by the file descriptor manager:
// 1) If the fdMgr is deleted and there are still
// 1) If the fdManager is deleted and there are still
// fdReg objects attached
// 2) Immediately after calling "callBack()" if
// the constructor specified "onceOnly"
@@ -94,11 +95,11 @@ private:
unsigned char onceOnly;
};
class fdMgr {
class fdManager {
friend class fdReg;
public:
fdMgr();
~fdMgr();
fdManager();
~fdManager();
void process (const osiTime &delay);
private:
tsDLList<fdReg> regList;
@@ -119,13 +120,13 @@ private:
fd_set *pFDSet (fdRegType typIn);
};
extern fdMgr fileDescriptorManager;
extern fdManager fileDescriptorManager;
//
// fdMgrMaxInt ()
// fdManagerMaxInt ()
//
inline int fdMgrMaxInt (int a, int b)
inline int fdManagerMaxInt (int a, int b)
{
if (a>b) {
return a;
@@ -136,9 +137,9 @@ inline int fdMgrMaxInt (int a, int b)
}
//
// fdMgr::pFDSet()
// fdManager::pFDSet()
//
inline fd_set *fdMgr::pFDSet (fdRegType typIn)
inline fd_set *fdManager::pFDSet (fdRegType typIn)
{
fd_set *pSet;
@@ -159,22 +160,22 @@ inline fd_set *fdMgr::pFDSet (fdRegType typIn)
}
//
// fdMgr::installReg()
// fdManager::installReg()
//
inline void fdMgr::installReg (fdReg &reg)
inline void fdManager::installReg (fdReg &reg)
{
this->maxFD = fdMgrMaxInt(this->maxFD, reg.fd+1);
this->maxFD = fdManagerMaxInt(this->maxFD, reg.fd+1);
this->regList.add(reg);
reg.state = fdrPending;
}
//
// fdMgr::removeReg()
// fdManager::removeReg()
//
inline void fdMgr::removeReg(fdReg &reg)
inline void fdManager::removeReg(fdReg &reg)
{
//
// signal fdMgr that the fdReg was deleted
// signal fdManager that the fdReg was deleted
// during the call back
//
if (this->pCBReg == &reg) {
@@ -214,5 +215,5 @@ inline fdReg::fdReg (const int fdIn, const fdRegType typIn,
fileDescriptorManager.installReg(*this);
}
#endif // fdMgrH_included
#endif // fdManagerH_included

View File

@@ -0,0 +1,210 @@
//
// $Id$
//
//
// $Log$
//
//
//
// NOTES:
// 1) This isnt intended for a multi-threading environment
//
//
//
// ANSI C
//
#include <assert.h>
#include <errno.h>
#include <string.h>
#if __GNUC__
extern "C" {
# include <sys/types.h>
int select (int, fd_set *, fd_set *,
fd_set *, struct timeval *);
int bzero (char *b, int length);
} //extern "C"
#endif // __GNUC__
#include <fdManager.h>
#include <osiTimer.h>
fdManager fileDescriptorManager;
inline int selectErrno()
{
return errno;
}
//
// fdManager::fdManager()
//
fdManager::fdManager()
{
FD_ZERO (&this->read);
FD_ZERO (&this->write);
FD_ZERO (&this->exception);
this->maxFD = 0;
this->processInProg = 0;
this->pCBReg = 0;
}
//
// fdManager::~fdManager()
//
fdManager::~fdManager()
{
fdReg *pReg;
while ( (pReg = this->regList.get()) ) {
pReg->state = fdrLimbo;
pReg->destroy();
}
while ( (pReg = this->activeList.get()) ) {
pReg->state = fdrLimbo;
pReg->destroy();
}
}
//
// fdManager::process()
//
void fdManager::process (const osiTime &delay)
{
tsDLIter<fdReg> regIter(this->regList);
osiTime minDelay;
osiTime zeroDelay;
fdReg *pReg;
struct timeval tv;
int status;
//
// no recursion
//
if (this->processInProg) {
return;
}
this->processInProg = 1;
while ( (pReg=regIter()) ) {
FD_SET(pReg->fd, &pReg->fdSet);
}
//
// dont bother calling select if the delay to
// the first timer expire is zero
//
while (1) {
minDelay = staticTimerQueue.delayToFirstExpire();
if (zeroDelay>=minDelay) {
staticTimerQueue.process();
}
else {
break;
}
}
if (minDelay>=delay) {
minDelay = delay;
}
minDelay.getTV (tv.tv_sec, tv.tv_usec);
status = select (this->maxFD, &this->read,
&this->write, &this->exception, &tv);
staticTimerQueue.process();
if (status==0) {
this->processInProg = 0;
return;
}
else if (status<0) {
if (selectErrno() == EINTR) {
this->processInProg = 0;
return;
}
else {
fprintf(stderr,
"fdManager: select failed because \"%s\"\n",
strerror(selectErrno()));
}
}
//
// Look for activity
//
regIter.reset();
while ( (pReg=regIter()) ) {
if (FD_ISSET(pReg->fd, &pReg->fdSet)) {
FD_CLR(pReg->fd, &pReg->fdSet);
regIter.remove();
this->activeList.add(*pReg);
pReg->state = fdrActive;
}
}
//
// I am careful to prevent problems if they access the
// above list while in a "callBack()" routine
//
while ( (pReg = this->activeList.get()) ) {
pReg->state = fdrLimbo;
//
// Tag current reg so that we
// can detect if it was deleted
// during the call back
//
this->pCBReg = pReg;
pReg->callBack();
if (this->pCBReg == pReg) {
this->pCBReg = 0;
if (pReg->onceOnly) {
pReg->destroy();
}
else {
this->regList.add(*pReg);
pReg->state = fdrPending;
}
}
else {
//
// no recursive calls to process allowed
//
assert(this->pCBReg == 0);
}
}
this->processInProg = 0;
}
//
// fdReg::destroy()
// (default destroy method)
//
void fdReg::destroy()
{
delete this;
}
//
// fdReg::~fdReg()
//
fdReg::~fdReg()
{
fileDescriptorManager.removeReg(*this);
}
//
// fdReg::show()
//
void fdReg::show(unsigned level)
{
printf ("fdReg at %x\n", (unsigned) this);
if (level>1u) {
printf ("\tfd = %d, fdSet at %x, state = %d, onceOnly = %d\n",
this->fd, (unsigned)&this->fdSet,
this->state, this->onceOnly);
}
}

View File

@@ -0,0 +1,219 @@
/*
* $Id$
*
* File descriptor management C++ class library
* (for multiplexing IO in a single threaded environment)
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
*
*/
#ifndef fdManagerH_included
#define fdManagerH_included
#include <tsDLList.h>
#include <osiTime.h>
#ifdef WIN32
#include <winsock.h>
#else
extern "C" {
# include <sys/types.h>
# include <sys/time.h>
} // extern "C"
#endif
#include <stdio.h>
enum fdRegType {fdrRead, fdrWrite, fdrExcp};
enum fdRegState {fdrActive, fdrPending, fdrLimbo};
//
// fdReg
// file descriptor registration
//
class fdReg : public tsDLNode<fdReg> {
friend class fdManager;
public:
fdReg (const int fdIn, const fdRegType typ,
const unsigned onceOnly=0);
virtual ~fdReg ();
virtual void show(unsigned level);
private:
//
// called when there is activity on the fd
// NOTES
// 1) the fdManager will call this only once during the
// lifetime of a fdReg object if the constructor
// specified "onceOnly"
//
virtual void callBack ()=0;
//
// Called by the file descriptor manager:
// 1) If the fdManager is deleted and there are still
// fdReg objects attached
// 2) Immediately after calling "callBack()" if
// the constructor specified "onceOnly"
//
// fdReg::destroy() does a "delete this"
//
virtual void destroy ();
const int fd;
fd_set &fdSet;
unsigned char state; // fdRegState goes here
unsigned char onceOnly;
};
class fdManager {
friend class fdReg;
public:
fdManager();
~fdManager();
void process (const osiTime &delay);
private:
tsDLList<fdReg> regList;
tsDLList<fdReg> activeList;
fd_set read;
fd_set write;
fd_set exception;
int maxFD;
unsigned processInProg;
//
// Set to fdreg when in call back
// and nill ortherwise
//
fdReg *pCBReg;
void installReg (fdReg &reg);
void removeReg (fdReg &reg);
fd_set *pFDSet (fdRegType typIn);
};
extern fdManager fileDescriptorManager;
//
// fdManagerMaxInt ()
//
inline int fdManagerMaxInt (int a, int b)
{
if (a>b) {
return a;
}
else {
return b;
}
}
//
// fdManager::pFDSet()
//
inline fd_set *fdManager::pFDSet (fdRegType typIn)
{
fd_set *pSet;
switch (typIn) {
case fdrRead:
pSet = &this->read;
break;
case fdrWrite:
pSet = &this->write;
break;
case fdrExcp:
pSet = &this->exception;
break;
default:
assert(0);
}
return pSet;
}
//
// fdManager::installReg()
//
inline void fdManager::installReg (fdReg &reg)
{
this->maxFD = fdManagerMaxInt(this->maxFD, reg.fd+1);
this->regList.add(reg);
reg.state = fdrPending;
}
//
// fdManager::removeReg()
//
inline void fdManager::removeReg(fdReg &reg)
{
//
// signal fdManager that the fdReg was deleted
// during the call back
//
if (this->pCBReg == &reg) {
this->pCBReg = 0;
}
FD_CLR(reg.fd, &reg.fdSet);
switch (reg.state) {
case fdrActive:
this->activeList.remove(reg);
reg.state = fdrLimbo;
break;
case fdrPending:
this->regList.remove(reg);
reg.state = fdrLimbo;
break;
case fdrLimbo:
break;
default:
assert(0);
}
}
//
// fdReg::fdReg()
//
inline fdReg::fdReg (const int fdIn, const fdRegType typIn,
const unsigned onceOnlyIn) :
fd(fdIn), fdSet(*fileDescriptorManager.pFDSet(typIn)),
state(fdrLimbo), onceOnly(onceOnlyIn)
{
assert (this->fd>=0);
if (this->fd>FD_SETSIZE) {
fprintf (stderr, "%s: fd > FD_SETSIZE ignored\n",
__FILE__);
return;
}
fileDescriptorManager.installReg(*this);
}
#endif // fdManagerH_included