Files
cdev-1.7.2n/extensions/cdevGenericServer/include/FD_Trigger.h
2022-12-13 12:44:04 +01:00

193 lines
4.5 KiB
C++

#ifndef _FD_TRIGGER_H_
#define _FD_TRIGGER_H_ 1
#include <cdevPlatforms.h>
// *****************************************************************************
// * FD_Trigger :
// * This class provides a method for triggering events based on file
// * descriptor activity.
// *****************************************************************************
class FD_Trigger
{
private:
enum {READ=0, WRITE=1};
int sockPair[2];
#ifndef _WIN32
char cbuf[100];
#endif
public:
FD_Trigger ( void );
~FD_Trigger ( void );
int insertEvent ( int numEvents = 1 );
int removeEvent ( int numEvents = 1 );
void purge ( void );
int writefd ( void ) const;
int readfd ( void ) const;
};
// *****************************************************************************
// * FD_Trigger::FD_Trigger :
// * Constructor for the FD_Trigger class.
// *****************************************************************************
inline FD_Trigger::FD_Trigger ( void )
{
if(pipe(sockPair)!=0)
{
sockPair[READ] = -1;
sockPair[WRITE] = -1;
}
#ifndef _WIN32
else
{
int val;
val = ::fcntl(sockPair[READ], F_GETFL, 0);
if(val>0) ::fcntl(sockPair[READ], F_SETFL, val|O_NONBLOCK);
val = ::fcntl(sockPair[WRITE], F_GETFL, 0);
if(val>0) ::fcntl(sockPair[WRITE], F_SETFL, val|O_NONBLOCK);
memset(cbuf, '1', 100);
}
#endif
}
// *****************************************************************************
// * FD_Trigger::~FD_Trigger :
// * Destructor for the FD_Trigger class.
// *****************************************************************************
inline FD_Trigger::~FD_Trigger ( void )
{
if(sockPair[READ] != -1) close(sockPair[READ]);
if(sockPair[WRITE] != -1) close(sockPair[WRITE]);
}
// *****************************************************************************
// * FD_Trigger::insertEvent :
// * Adds one or more bytes (indicating events) to the pipe
// *****************************************************************************
inline int FD_Trigger::insertEvent ( int numEvents )
{
if(sockPair[WRITE]>0)
{
int count = 0;
#ifdef _WIN32
char cptr = 1;
while(count++<numEvents) send(sockPair[WRITE], &cptr, 1, 0);
#else
count = numEvents;
while(count>0)
{
write(sockPair[WRITE], cbuf, min(100, count));
count-=100;
}
#endif
}
return (sockPair[WRITE]>0)?0:-1;
}
// *****************************************************************************
// * FD_Trigger::removeEvent :
// * Removes one or more bytes (indicating events) from the pipe.
// *****************************************************************************
inline int FD_Trigger::removeEvent ( int numEvents )
{
int retval = 0;
if(sockPair[READ]>0)
{
int count = 0;
#ifdef _WIN32
char cptr = 0;
while(count<numEvents &&
(recv(sockPair[READ], &cptr, 1, 0)>0 ||
WSAGetLastError()==WSAEMSGSIZE))
{
count++;
}
if(count==0) retval = -1;
#else
if(ioctl(sockPair[READ], FIONREAD, &count)<0 || count==0)
{
retval = -1;
}
else
{
if(numEvents>count) numEvents = count;
while(numEvents>0)
{
read(sockPair[READ], cbuf, min(100, numEvents));
numEvents-=100;
}
}
#endif
}
else retval = -1;
return retval;
}
// *****************************************************************************
// * FD_Trigger::purge :
// * This function removes all bytes from the pipe.
// *****************************************************************************
inline void FD_Trigger::purge ( void )
{
if(sockPair[READ]>0)
{
#ifdef _WIN32
char cptr = 0;
while(recv(sockPair[READ], &cptr, 1, 0)>0 || WSAGetLastError()==WSAEMSGSIZE);
#else
int count = 0;
ioctl(sockPair[READ], FIONREAD, &count);
while(count>0)
{
read(sockPair[READ], cbuf, min(100, count));
count-=100;
}
#endif
}
}
// *****************************************************************************
// * FD_Trigger::writefd
// * Returns the write file descriptor associated with the pipe.
// *****************************************************************************
inline int FD_Trigger::writefd ( void ) const
{
return sockPair[WRITE];
}
// *****************************************************************************
// * FD_Trigger::readfd
// * Returns the read file descriptor associated with the pipe.
// *****************************************************************************
inline int FD_Trigger::readfd ( void ) const
{
return sockPair[READ];
}
#endif /* _FD_TRIGGER_H_ */