#ifndef _FD_TRIGGER_H_ #define _FD_TRIGGER_H_ 1 #include // ***************************************************************************** // * 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++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(count0 || 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_ */