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

254 lines
8.0 KiB
C++

//---------------------------------------------------------------------------
// Copyright (c) 1991,1992 Southeastern Universities Research Association,
// Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//----------------------------------------------------------------------------
//
// description: cdevSelector.h
// The cdevSelector class provides a mechanism for cdevServices to provide
// a locally changable file descriptor to the cdevSystem for select
// operations.
//
// If the service does not support or require file descriptors to operate,
// it may make one of these objects in its constructor and then provide
// the 'readfd' to the cdevSystem when it calls the services getFD method.
// The service may then 'insertEvents' into the object, which will in-turn
// cause the cdevSystems select mechanism to call the service. Once the
// service has responded to the events it should call 'removeEvents' to
// prevent the select mechanism from being triggered again.
//
// Author: Walt Akers
//
// Revision History:
// cdevSelector.h,v
// Revision 1.3 1996/12/05 21:10:49 akers
// Changes to support multiple CDEV DDL versions
//
// Revision 1.2 1995/10/19 20:16:55 akers
// Added capability to test the read file descriptor for data before reading
//
// Revision 1.1 1995/08/18 16:23:41 akers
// Mechanism for providing file descriptor selection for services.
//
//
#ifndef _CDEV_SELECTOR_H_
#define _CDEV_SELECTOR_H_
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#if defined(solaris) || defined(SunOS)
#include <sys/filio.h>
#endif
class cdevSelector
{
private:
typedef struct
{
int readfd;
int writefd;
} SocketPair;
SocketPair sp;
char cbuf[21];
public:
cdevSelector ( void );
~cdevSelector ( void );
int insertEvent ( int numEvents = 1 );
int removeEvent ( int numEvents = 1 );
void purge ( void );
int writefd ( void );
int readfd ( void );
};
// *****************************************************************************
// * cdevSelector::cdevSelector :
// * Constructor for the cdevSelector class.
// *****************************************************************************
inline cdevSelector::cdevSelector ( void )
{
if(pipe((int *)&sp)!=0)
{
sp.readfd = -1;
sp.writefd = -1;
}
else
{
int val;
val = ::fcntl(sp.readfd, F_GETFL, 0);
if(val>0) ::fcntl(sp.readfd, F_SETFL, val|O_NONBLOCK);
val = ::fcntl(sp.writefd, F_GETFL, 0);
if(val>0) ::fcntl(sp.writefd, F_SETFL, val|O_NONBLOCK);
}
}
// *****************************************************************************
// * cdevSelector::~cdevSelector :
// * Destructor for the cdevSelector class.
// *****************************************************************************
inline cdevSelector::~cdevSelector ( void )
{
if(sp.readfd != -1) close(sp.readfd);
if(sp.writefd != -1) close(sp.writefd);
}
// *****************************************************************************
// * cdevSelector::insertEvent :
// * Adds one or more bytes (indicating events) to the pipe
// *****************************************************************************
inline int cdevSelector::insertEvent ( int numEvents )
{
int result = 0;
char *cptr = cbuf;
// *********************************************************************
// * If the write file descriptor is valid
// *********************************************************************
if(sp.writefd>0)
{
// *************************************************************
// * If the user wants to add more bytes than the buffer can
// * handle, allocated a sufficient buffer to hold the data.
// *************************************************************
if(numEvents>20) cptr = new char[numEvents];
// *************************************************************
// * Write the specified number of bytes to the buffer.
// *************************************************************
write(sp.writefd, cptr, numEvents);
// *************************************************************
// * Delete the buffer if it was allocated locally.
// *************************************************************
if(cptr!=cbuf) delete cptr;
}
else result = -1;
return result;
}
// *****************************************************************************
// * cdevSelector::removeEvent :
// * Removes one or more bytes (indicating events) from the pipe.
// *****************************************************************************
inline int cdevSelector::removeEvent ( int numEvents )
{
int result = 0;
char *cptr = cbuf;
// *********************************************************************
// * If the read file descriptor is valid.
// *********************************************************************
if(sp.readfd>0)
{
int count;
// *************************************************************
// * Find out how many bytes are ready to read.
// *************************************************************
ioctl(sp.readfd, FIONREAD, &count);
if(numEvents>count) numEvents = count;
if(numEvents>0)
{
// *****************************************************
// * If the user wants to remove more bytes than the
// * buffer can handle, allocated a sufficient buffer to
// * hold the data.
// *****************************************************
if(numEvents>20) cptr = new char[numEvents];
// *****************************************************
// * Read the specified number of bytes from the pipe.
// *****************************************************
read(sp.readfd, cptr, numEvents);
// *****************************************************
// * Delete the buffer if it was allocated locally.
// *****************************************************
if(cptr!=cbuf) delete cptr;
}
}
else result = -1;
return result;
}
// *****************************************************************************
// * cdevSelector::purge :
// * This function removes all bytes from the pipe.
// *****************************************************************************
inline void cdevSelector::purge ( void )
{
int count;
char * cptr = cbuf;
if(sp.readfd>0)
{
// *************************************************************
// * Find out how many bytes are ready to read.
// *************************************************************
ioctl(sp.readfd, FIONREAD, &count);
if(count>0)
{
// *****************************************************
// * If the user wants to remove more bytes than the
// * buffer can handle, allocated a sufficient buffer to
// * hold the data.
// *****************************************************
if(count>20) cptr = new char[count];
// *****************************************************
// * Read the specified number of bytes from the pipe.
// *****************************************************
read(sp.readfd, cptr, count);
// *****************************************************
// * Delete the buffer if it was allocated locally.
// *****************************************************
if(cptr!=cbuf) delete cptr;
}
}
}
// *****************************************************************************
// * cdevSelector::writefd
// * Returns the write file descriptor associated with the pipe.
// *****************************************************************************
inline int cdevSelector::writefd ( void )
{
return sp.writefd;
}
// *****************************************************************************
// * cdevSelector::readfd
// * Returns the read file descriptor associated with the pipe.
// *****************************************************************************
inline int cdevSelector::readfd ( void )
{
return sp.readfd;
}
#endif /* _CDEV_SELECTOR_H_ */