#ifndef __JNET__JSELECT__ #define __JNET__JSELECT__ #include #include #include #include #include "JLang/JException.hh" #include "JLang/JFileDescriptorMask.hh" #include "JLang/JAbstractFile.hh" #include "JLang/JTimeval.hh" #include "JNet/JSelectReader.hh" #include "JNet/JSelectWriter.hh" /** * \author mdejong */ namespace JNET {} namespace JPP { using namespace JNET; } namespace JNET { using JLANG::JTimeval; using JLANG::JSelectException; /** * Wrapper class for select call. */ class JSelect : public JSelectReader, public JSelectWriter { public: /** * Default constructor. */ JSelect() : JSelectReader(), JSelectWriter() {} /** * Reset. */ void reset() { static_cast(*this).reset(); static_cast(*this).reset(); } /** * Infinite wait select call. * * \return true if data can be read or written; else false */ bool operator ()() { return this->operator ()(0); } /** * Select call. * * \param timeout timeout * \return true if data can be read or written; else false */ bool operator()(JTimeval timeout) { return this->operator ()(static_cast(static_cast(&timeout))); } /** * Select call. * * \return number of valid file descriptors */ int operator()(JTimeval* timeout) { int nfds = std::max(readerMask.getNumberOfFileDescriptors(), writerMask.getNumberOfFileDescriptors()); nfds += 1; nfds = ::select(nfds, &readerMask, &writerMask, NULL, timeout->get()); if (nfds != 0) { if (nfds < 0) { readerMask.reset(true); // hard reset writerMask.reset(true); // hard reset if (errno != EINTR) { THROW(JSelectException, "select(..) failed " << nfds << "; errno = " << errno); } } } else { readerMask.reset(false); // soft reset writerMask.reset(false); // soft reset } return nfds; } }; } #endif