diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b0d288f9..7ab1da523 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -678,6 +678,7 @@ CHECK_INCLUDE_FILE_CXX(poll.h HAVE_POLL_H) CHECK_INCLUDE_FILE_CXX(sys/inotify.h HAVE_SYS_INOTIFY_H) CHECK_INCLUDE_FILE_CXX(sys/timerfd.h HAVE_SYS_TIMERFD_H) CHECK_INCLUDE_FILE_CXX(sys/socket.h HAVE_SYS_SOCKET_H) +CHECK_INCLUDE_FILE_CXX(sys/eventfd.h HAVE_SYS_EVENTFD_H) CHECK_INCLUDE_FILE_CXX(sys/file.h HAVE_SYS_FILE_H) if(USE_CONSOLE) CHECK_INCLUDE_FILE_CXX(readline.h HAVE_READLINE_H) diff --git a/config.h.cmake b/config.h.cmake index 496b43385..5c24d626d 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -91,6 +91,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_INOTIFY_H 1 +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_EVENTFD_H + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_FILE_H 1 diff --git a/config.h.in b/config.h.in index 0c16d7085..0ae6d1640 100644 --- a/config.h.in +++ b/config.h.in @@ -90,6 +90,9 @@ /* inotify reachable using syscall */ #undef HAVE_SYSCALL_INOTIFY +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_EVENTFD_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H diff --git a/configure.ac b/configure.ac index 3c6b4f600..5fe5e6693 100644 --- a/configure.ac +++ b/configure.ac @@ -56,7 +56,7 @@ AM_CONDITIONAL(MACOSX, [test $osx = true]) # various used headers dnl the whitespace is there to prevent AC_INCLUDES_DEFAULT -AC_CHECK_HEADERS([stdint.h unistd.h poll.h sys/file.h sys/stat.h sys/types.h locale.h sys/socket.h signal.h langinfo.h sys/timerfd.h sys/inotify.h sys/syscall.h], , , [[ ]]) +AC_CHECK_HEADERS([stdint.h unistd.h poll.h sys/file.h sys/stat.h sys/types.h locale.h sys/socket.h signal.h langinfo.h sys/eventfd.h sys/timerfd.h sys/inotify.h sys/syscall.h], , , [[ ]]) # Mingw does not ship with multimon.h AC_CHECK_HEADERS([multimon.h io.h direct.h share.h], [], [], [[#include ]]) # iconv diff --git a/src/platform/StdScheduler.cpp b/src/platform/StdScheduler.cpp index 77d940120..22b862a26 100644 --- a/src/platform/StdScheduler.cpp +++ b/src/platform/StdScheduler.cpp @@ -522,7 +522,7 @@ namespace { void Fail(const char* msg) { - // TODO: throw std::runtime_error(msg); ? + Log(msg); } } @@ -536,12 +536,37 @@ bool CStdNotifyProc::CheckAndReset() return true; } #else // STDSCHEDULER_USE_EVENTS +#ifdef HAVE_SYS_EVENTFD_H +#include + +CStdNotifyProc::CStdNotifyProc() +{ + // FIXME: Once linux version 2.6.27 is required, use EFD_NONBLOCK and EFD_CLOEXEC + fds[0] = eventfd(0, 0); + if (fds[0] == -1) + Fail("eventfd failed"); + fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK); + fcntl(fds[0], F_SETFD, FD_CLOEXEC); +} +void CStdNotifyProc::Notify() +{ + uint64_t n = 1; + if (write(fds[0], &n, 8) == -1) + Fail("write failed"); +} +bool CStdNotifyProc::CheckAndReset() +{ + uint64_t n; + return (read(fds[0], &n, 8) != -1); +} +#else CStdNotifyProc::CStdNotifyProc() { if (pipe(fds) == -1) Fail("pipe failed"); - // Experimental castration of the pipe. fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK); + fcntl(fds[0], F_SETFD, FD_CLOEXEC); + fcntl(fds[1], F_SETFD, FD_CLOEXEC); } void CStdNotifyProc::Notify() { @@ -563,6 +588,12 @@ bool CStdNotifyProc::CheckAndReset() return r; } #endif +void CStdNotifyProc::GetFDs(std::vector & checkfds) +{ + pollfd pfd = { fds[0], POLLIN, 0 }; + checkfds.push_back(pfd); +} +#endif /* CStdMultimediaTimerProc */ #ifdef STDSCHEDULER_USE_EVENTS diff --git a/src/platform/StdScheduler.h b/src/platform/StdScheduler.h index 031a7d8b8..0b3e15a3a 100644 --- a/src/platform/StdScheduler.h +++ b/src/platform/StdScheduler.h @@ -139,11 +139,7 @@ private: int fds[2]; public: // StdSchedulerProc override - virtual void GetFDs(std::vector & checkfds) - { - pollfd pfd = { fds[0], POLLIN, 0 }; - checkfds.push_back(pfd); - } + virtual void GetFDs(std::vector & checkfds); #endif };