fixed several subtle bugs
This commit is contained in:
@@ -4,6 +4,9 @@
|
||||
//
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.2 1996/09/04 21:50:16 jhill
|
||||
// added hashed fd to fdi convert
|
||||
//
|
||||
// Revision 1.1 1996/08/13 22:48:23 jhill
|
||||
// dfMgr =>fdManager
|
||||
//
|
||||
@@ -12,7 +15,7 @@
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
// 1) This isnt intended for a multi-threading environment
|
||||
// 1) This library is not thread safe
|
||||
//
|
||||
//
|
||||
|
||||
@@ -23,17 +26,23 @@
|
||||
#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__
|
||||
// Both the functions in osiTimer and fdManager are
|
||||
// implemented in this DLL -> define epicsExportSharesSymbols
|
||||
#define epicsExportSharedSymbols
|
||||
#include "osiTimer.h"
|
||||
#include "fdManager.h"
|
||||
|
||||
#include <fdManager.h>
|
||||
#include <osiTimer.h>
|
||||
#if !defined(__SUNPRO_CC)
|
||||
//
|
||||
// From Stroustrups's "The C++ Programming Language"
|
||||
// Appendix A: r.14.9
|
||||
//
|
||||
// This explicitly instantiates the template class's member
|
||||
// functions into "fdManager.o"
|
||||
//
|
||||
# include <resourceLib.cc>
|
||||
template class resTable <fdReg, fdRegId>;
|
||||
#endif
|
||||
|
||||
fdManager fileDescriptorManager;
|
||||
|
||||
@@ -85,7 +94,7 @@ fdManager::~fdManager()
|
||||
//
|
||||
void fdManager::process (const osiTime &delay)
|
||||
{
|
||||
tsDLIter<fdReg> regIter(this->regList);
|
||||
tsDLFwdIter<fdReg> regIter(this->regList);
|
||||
osiTime minDelay;
|
||||
osiTime zeroDelay;
|
||||
fdReg *pReg;
|
||||
@@ -100,27 +109,26 @@ void fdManager::process (const osiTime &delay)
|
||||
}
|
||||
this->processInProg = 1;
|
||||
|
||||
while ( (pReg=regIter()) ) {
|
||||
FD_SET(pReg->getFD(), &this->fdSets[pReg->getType()]);
|
||||
}
|
||||
|
||||
//
|
||||
// dont bother calling select if the delay to
|
||||
// the first timer expire is zero
|
||||
// One shot at expired timers prior to going into
|
||||
// select. This allows zero delay timers to arm
|
||||
// fd writes. We will never process the timer queue
|
||||
// more than once here so that fd activity get serviced
|
||||
// in a reasonable length of time.
|
||||
//
|
||||
while (1) {
|
||||
minDelay = staticTimerQueue.delayToFirstExpire();
|
||||
if (zeroDelay>=minDelay) {
|
||||
staticTimerQueue.process();
|
||||
minDelay = staticTimerQueue.delayToFirstExpire();
|
||||
if (zeroDelay>=minDelay) {
|
||||
staticTimerQueue.process();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minDelay>=delay) {
|
||||
minDelay = delay;
|
||||
}
|
||||
|
||||
while ( (pReg=regIter()) ) {
|
||||
FD_SET(pReg->getFD(), &this->fdSets[pReg->getType()]);
|
||||
}
|
||||
minDelay.getTV (tv.tv_sec, tv.tv_usec);
|
||||
status = select (this->maxFD, &this->fdSets[fdrRead],
|
||||
&this->fdSets[fdrWrite], &this->fdSets[fdrExcp], &tv);
|
||||
@@ -208,7 +216,7 @@ fdReg::~fdReg()
|
||||
//
|
||||
// fdReg::show()
|
||||
//
|
||||
void fdReg::show(unsigned level)
|
||||
void fdReg::show(unsigned level) const
|
||||
{
|
||||
printf ("fdReg at %x\n", (unsigned) this);
|
||||
if (level>1u) {
|
||||
@@ -221,7 +229,7 @@ void fdReg::show(unsigned level)
|
||||
//
|
||||
// fdRegId::show()
|
||||
//
|
||||
void fdRegId::show(unsigned level)
|
||||
void fdRegId::show(unsigned level) const
|
||||
{
|
||||
printf ("fdRegId at %x\n", (unsigned) this);
|
||||
if (level>1u) {
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.2 1996/09/04 21:50:16 jhill
|
||||
* added hashed fd to fdi convert
|
||||
*
|
||||
* Revision 1.1 1996/08/13 22:48:21 jhill
|
||||
* dfMgr =>fdManager
|
||||
*
|
||||
@@ -41,21 +44,13 @@
|
||||
#ifndef fdManagerH_included
|
||||
#define fdManagerH_included
|
||||
|
||||
#include <tsDLList.h>
|
||||
#include <resourceLib.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>
|
||||
|
||||
#include "tsDLList.h"
|
||||
#include "resourceLib.h"
|
||||
#include "osiTime.h"
|
||||
#include "osiSock.h"
|
||||
|
||||
enum fdRegType {fdrRead, fdrWrite, fdrExcp, fdRegTypeNElem};
|
||||
enum fdRegState {fdrActive, fdrPending, fdrLimbo};
|
||||
|
||||
@@ -100,7 +95,7 @@ public:
|
||||
return hashid;
|
||||
}
|
||||
|
||||
virtual void show(unsigned level);
|
||||
virtual void show(unsigned level) const;
|
||||
private:
|
||||
const int fd;
|
||||
const fdRegType type;
|
||||
@@ -110,15 +105,15 @@ private:
|
||||
// fdReg
|
||||
// file descriptor registration
|
||||
//
|
||||
class fdReg : public tsDLNode<fdReg>, public fdRegId,
|
||||
class epicsShareClass fdReg : public tsDLNode<fdReg>, public fdRegId,
|
||||
public tsSLNode<fdReg> {
|
||||
friend class fdManager;
|
||||
public:
|
||||
fdReg (const int fdIn, const fdRegType typ,
|
||||
inline fdReg (const int fdIn, const fdRegType typ,
|
||||
const unsigned onceOnly=0);
|
||||
virtual ~fdReg ();
|
||||
|
||||
virtual void show(unsigned level);
|
||||
virtual void show(unsigned level) const;
|
||||
private:
|
||||
|
||||
//
|
||||
@@ -145,7 +140,7 @@ private:
|
||||
unsigned char onceOnly;
|
||||
};
|
||||
|
||||
class fdManager {
|
||||
class epicsShareClass fdManager {
|
||||
friend class fdReg;
|
||||
public:
|
||||
fdManager();
|
||||
@@ -155,7 +150,7 @@ public:
|
||||
//
|
||||
// returns NULL if the fd is unknown
|
||||
//
|
||||
fdReg *lookUpFD(const int fd, const fdRegType type);
|
||||
inline fdReg *lookUpFD(const int fd, const fdRegType type);
|
||||
private:
|
||||
tsDLList<fdReg> regList;
|
||||
tsDLList<fdReg> activeList;
|
||||
@@ -168,12 +163,12 @@ private:
|
||||
//
|
||||
fdReg *pCBReg;
|
||||
|
||||
void installReg (fdReg ®);
|
||||
void removeReg (fdReg ®);
|
||||
inline void installReg (fdReg ®);
|
||||
inline void removeReg (fdReg ®);
|
||||
resTable<fdReg,fdRegId> fdTbl;
|
||||
};
|
||||
|
||||
extern fdManager fileDescriptorManager;
|
||||
epicsShareExtern fdManager fileDescriptorManager;
|
||||
|
||||
//
|
||||
// lookUpFD()
|
||||
@@ -259,7 +254,7 @@ inline fdReg::fdReg (const int fdIn, const fdRegType typIn,
|
||||
fdRegId(fdIn,typIn), state(fdrLimbo), onceOnly(onceOnlyIn)
|
||||
{
|
||||
assert (fdIn>=0);
|
||||
if (fdIn>FD_SETSIZE) {
|
||||
if (!FD_IN_FDSET(fdIn)) {
|
||||
fprintf (stderr, "%s: fd > FD_SETSIZE ignored\n",
|
||||
__FILE__);
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
//
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.2 1996/09/04 21:50:16 jhill
|
||||
// added hashed fd to fdi convert
|
||||
//
|
||||
// Revision 1.1 1996/08/13 22:48:23 jhill
|
||||
// dfMgr =>fdManager
|
||||
//
|
||||
@@ -12,7 +15,7 @@
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
// 1) This isnt intended for a multi-threading environment
|
||||
// 1) This library is not thread safe
|
||||
//
|
||||
//
|
||||
|
||||
@@ -23,17 +26,23 @@
|
||||
#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__
|
||||
// Both the functions in osiTimer and fdManager are
|
||||
// implemented in this DLL -> define epicsExportSharesSymbols
|
||||
#define epicsExportSharedSymbols
|
||||
#include "osiTimer.h"
|
||||
#include "fdManager.h"
|
||||
|
||||
#include <fdManager.h>
|
||||
#include <osiTimer.h>
|
||||
#if !defined(__SUNPRO_CC)
|
||||
//
|
||||
// From Stroustrups's "The C++ Programming Language"
|
||||
// Appendix A: r.14.9
|
||||
//
|
||||
// This explicitly instantiates the template class's member
|
||||
// functions into "fdManager.o"
|
||||
//
|
||||
# include <resourceLib.cc>
|
||||
template class resTable <fdReg, fdRegId>;
|
||||
#endif
|
||||
|
||||
fdManager fileDescriptorManager;
|
||||
|
||||
@@ -85,7 +94,7 @@ fdManager::~fdManager()
|
||||
//
|
||||
void fdManager::process (const osiTime &delay)
|
||||
{
|
||||
tsDLIter<fdReg> regIter(this->regList);
|
||||
tsDLFwdIter<fdReg> regIter(this->regList);
|
||||
osiTime minDelay;
|
||||
osiTime zeroDelay;
|
||||
fdReg *pReg;
|
||||
@@ -100,27 +109,26 @@ void fdManager::process (const osiTime &delay)
|
||||
}
|
||||
this->processInProg = 1;
|
||||
|
||||
while ( (pReg=regIter()) ) {
|
||||
FD_SET(pReg->getFD(), &this->fdSets[pReg->getType()]);
|
||||
}
|
||||
|
||||
//
|
||||
// dont bother calling select if the delay to
|
||||
// the first timer expire is zero
|
||||
// One shot at expired timers prior to going into
|
||||
// select. This allows zero delay timers to arm
|
||||
// fd writes. We will never process the timer queue
|
||||
// more than once here so that fd activity get serviced
|
||||
// in a reasonable length of time.
|
||||
//
|
||||
while (1) {
|
||||
minDelay = staticTimerQueue.delayToFirstExpire();
|
||||
if (zeroDelay>=minDelay) {
|
||||
staticTimerQueue.process();
|
||||
minDelay = staticTimerQueue.delayToFirstExpire();
|
||||
if (zeroDelay>=minDelay) {
|
||||
staticTimerQueue.process();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minDelay>=delay) {
|
||||
minDelay = delay;
|
||||
}
|
||||
|
||||
while ( (pReg=regIter()) ) {
|
||||
FD_SET(pReg->getFD(), &this->fdSets[pReg->getType()]);
|
||||
}
|
||||
minDelay.getTV (tv.tv_sec, tv.tv_usec);
|
||||
status = select (this->maxFD, &this->fdSets[fdrRead],
|
||||
&this->fdSets[fdrWrite], &this->fdSets[fdrExcp], &tv);
|
||||
@@ -208,7 +216,7 @@ fdReg::~fdReg()
|
||||
//
|
||||
// fdReg::show()
|
||||
//
|
||||
void fdReg::show(unsigned level)
|
||||
void fdReg::show(unsigned level) const
|
||||
{
|
||||
printf ("fdReg at %x\n", (unsigned) this);
|
||||
if (level>1u) {
|
||||
@@ -221,7 +229,7 @@ void fdReg::show(unsigned level)
|
||||
//
|
||||
// fdRegId::show()
|
||||
//
|
||||
void fdRegId::show(unsigned level)
|
||||
void fdRegId::show(unsigned level) const
|
||||
{
|
||||
printf ("fdRegId at %x\n", (unsigned) this);
|
||||
if (level>1u) {
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
*
|
||||
* History
|
||||
* $Log$
|
||||
* Revision 1.2 1996/09/04 21:50:16 jhill
|
||||
* added hashed fd to fdi convert
|
||||
*
|
||||
* Revision 1.1 1996/08/13 22:48:21 jhill
|
||||
* dfMgr =>fdManager
|
||||
*
|
||||
@@ -41,21 +44,13 @@
|
||||
#ifndef fdManagerH_included
|
||||
#define fdManagerH_included
|
||||
|
||||
#include <tsDLList.h>
|
||||
#include <resourceLib.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>
|
||||
|
||||
#include "tsDLList.h"
|
||||
#include "resourceLib.h"
|
||||
#include "osiTime.h"
|
||||
#include "osiSock.h"
|
||||
|
||||
enum fdRegType {fdrRead, fdrWrite, fdrExcp, fdRegTypeNElem};
|
||||
enum fdRegState {fdrActive, fdrPending, fdrLimbo};
|
||||
|
||||
@@ -100,7 +95,7 @@ public:
|
||||
return hashid;
|
||||
}
|
||||
|
||||
virtual void show(unsigned level);
|
||||
virtual void show(unsigned level) const;
|
||||
private:
|
||||
const int fd;
|
||||
const fdRegType type;
|
||||
@@ -110,15 +105,15 @@ private:
|
||||
// fdReg
|
||||
// file descriptor registration
|
||||
//
|
||||
class fdReg : public tsDLNode<fdReg>, public fdRegId,
|
||||
class epicsShareClass fdReg : public tsDLNode<fdReg>, public fdRegId,
|
||||
public tsSLNode<fdReg> {
|
||||
friend class fdManager;
|
||||
public:
|
||||
fdReg (const int fdIn, const fdRegType typ,
|
||||
inline fdReg (const int fdIn, const fdRegType typ,
|
||||
const unsigned onceOnly=0);
|
||||
virtual ~fdReg ();
|
||||
|
||||
virtual void show(unsigned level);
|
||||
virtual void show(unsigned level) const;
|
||||
private:
|
||||
|
||||
//
|
||||
@@ -145,7 +140,7 @@ private:
|
||||
unsigned char onceOnly;
|
||||
};
|
||||
|
||||
class fdManager {
|
||||
class epicsShareClass fdManager {
|
||||
friend class fdReg;
|
||||
public:
|
||||
fdManager();
|
||||
@@ -155,7 +150,7 @@ public:
|
||||
//
|
||||
// returns NULL if the fd is unknown
|
||||
//
|
||||
fdReg *lookUpFD(const int fd, const fdRegType type);
|
||||
inline fdReg *lookUpFD(const int fd, const fdRegType type);
|
||||
private:
|
||||
tsDLList<fdReg> regList;
|
||||
tsDLList<fdReg> activeList;
|
||||
@@ -168,12 +163,12 @@ private:
|
||||
//
|
||||
fdReg *pCBReg;
|
||||
|
||||
void installReg (fdReg ®);
|
||||
void removeReg (fdReg ®);
|
||||
inline void installReg (fdReg ®);
|
||||
inline void removeReg (fdReg ®);
|
||||
resTable<fdReg,fdRegId> fdTbl;
|
||||
};
|
||||
|
||||
extern fdManager fileDescriptorManager;
|
||||
epicsShareExtern fdManager fileDescriptorManager;
|
||||
|
||||
//
|
||||
// lookUpFD()
|
||||
@@ -259,7 +254,7 @@ inline fdReg::fdReg (const int fdIn, const fdRegType typIn,
|
||||
fdRegId(fdIn,typIn), state(fdrLimbo), onceOnly(onceOnlyIn)
|
||||
{
|
||||
assert (fdIn>=0);
|
||||
if (fdIn>FD_SETSIZE) {
|
||||
if (!FD_IN_FDSET(fdIn)) {
|
||||
fprintf (stderr, "%s: fd > FD_SETSIZE ignored\n",
|
||||
__FILE__);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user