//------------------------------------------------------------------------------
// File: EventFD.hh
// Author: Georgios Bitzes - CERN
//------------------------------------------------------------------------------
/************************************************************************
* qclient - A simple redis C++ client with support for redirects *
* Copyright (C) 2016 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#ifndef __QCLIENT_EVENTFD_H__
#define __QCLIENT_EVENTFD_H__
#include
#include
#include
#include
#include
namespace qclient {
// We use pipe for now, not the kernel sys/eventfd.h. :P Not supported on Mac OS.
class EventFD {
public:
EventFD() {
int status = pipe(fildes);
if(status != 0) {
std::cerr << "EventFD: CRITICAL: Could not obtain file descriptors for EventFD class, errno = " << errno << std::endl;
std::abort();
}
for(size_t i = 0; i < 2; i++) {
int flags = fcntl(fildes[i], F_GETFL, 0);
int status = fcntl(fildes[i], F_SETFL, flags | O_NONBLOCK);
if(status != 0) {
std::cerr << "EventFD: CRITICAL: Could not set file descriptor as non-blocking" << std::endl;
std::abort();
}
}
}
~EventFD() {
close();
}
void close() {
::close(fildes[0]);
::close(fildes[1]);
}
void notify() {
char val = 1;
int rc = write(fildes[1], &val, sizeof(val));
if (rc != sizeof(val)) {
std::cerr << "qclient: CRITICAL: could not write to EventFD pipe, return code "
<< rc << ": " << strerror(errno) << std::endl;
}
}
inline int getFD() const {
return fildes[0];
}
void clear() {
while(true) {
char buffer[128];
int rc = ::read(fildes[0], buffer, 64);
if(rc <= 0) {
break;
}
}
}
private:
int fildes[2];
};
}
#endif