dfMgr =>fdManager
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -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 ®)
|
||||
inline void fdManager::installReg (fdReg ®)
|
||||
{
|
||||
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 ®)
|
||||
inline void fdManager::removeReg(fdReg ®)
|
||||
{
|
||||
//
|
||||
// signal fdMgr that the fdReg was deleted
|
||||
// signal fdManager that the fdReg was deleted
|
||||
// during the call back
|
||||
//
|
||||
if (this->pCBReg == ®) {
|
||||
@@ -214,5 +215,5 @@ inline fdReg::fdReg (const int fdIn, const fdRegType typIn,
|
||||
fileDescriptorManager.installReg(*this);
|
||||
}
|
||||
|
||||
#endif // fdMgrH_included
|
||||
#endif // fdManagerH_included
|
||||
|
||||
210
src/libCom/fdmgr/fdManager.cpp
Normal file
210
src/libCom/fdmgr/fdManager.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
219
src/libCom/fdmgr/fdManager.h
Normal file
219
src/libCom/fdmgr/fdManager.h
Normal 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 ®);
|
||||
void removeReg (fdReg ®);
|
||||
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 ®)
|
||||
{
|
||||
this->maxFD = fdManagerMaxInt(this->maxFD, reg.fd+1);
|
||||
this->regList.add(reg);
|
||||
reg.state = fdrPending;
|
||||
}
|
||||
|
||||
//
|
||||
// fdManager::removeReg()
|
||||
//
|
||||
inline void fdManager::removeReg(fdReg ®)
|
||||
{
|
||||
//
|
||||
// signal fdManager that the fdReg was deleted
|
||||
// during the call back
|
||||
//
|
||||
if (this->pCBReg == ®) {
|
||||
this->pCBReg = 0;
|
||||
}
|
||||
FD_CLR(reg.fd, ®.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
|
||||
|
||||
Reference in New Issue
Block a user