diff --git a/CMakeLists.txt b/CMakeLists.txt index 45c9e1baf..98c23176f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,6 +208,7 @@ if(NOT ANDROID) endif() if(UNIX OR CYGWIN) + check_include_files(sys/eventfd.h HAVE_EVENTFD_H) set(X11_FEATURE_TYPE "RECOMMENDED") else() set(X11_FEATURE_TYPE "DISABLED") diff --git a/config.h.in b/config.h.in index d8717f3a5..8cbaf2620 100644 --- a/config.h.in +++ b/config.h.in @@ -28,7 +28,7 @@ #cmakedefine HAVE_SYS_MODEM_H #cmakedefine HAVE_SYS_FILIO_H #cmakedefine HAVE_SYS_STRTIO_H - +#cmakedefine HAVE_EVENTFD_H #cmakedefine HAVE_TM_GMTOFF diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index dd9463fca..9ce02230b 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -35,6 +35,12 @@ #include #endif + +#ifdef HAVE_EVENTFD_H +#include +#include +#endif + CRITICAL_SECTION cs = { NULL, 0, 0, NULL, NULL, 0 }; HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) @@ -57,11 +63,20 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, event->pipe_fd[0] = -1; event->pipe_fd[1] = -1; +#ifdef HAVE_EVENTFD_H + event->pipe_fd[0] = eventfd(0, EFD_NONBLOCK); + if (event->pipe_fd[0] < 0) + { + printf("CreateEventW: failed to create event\n"); + return NULL; + } +#else if (pipe(event->pipe_fd) < 0) { printf("CreateEventW: failed to create event\n"); return NULL; } +#endif handle = winpr_Handle_Insert(HANDLE_TYPE_EVENT, event); } @@ -113,7 +128,16 @@ BOOL SetEvent(HANDLE hEvent) { event = (WINPR_EVENT*) Object; - if (!(WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)) +#ifdef HAVE_EVENTFD_H + eventfd_t val = 1; + do + { + length = eventfd_write(event->pipe_fd[0], val); + } + while(length < 0 && errno == EINTR); + status = (length == 0) ? TRUE : FALSE; +#else + if (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0) { length = write(event->pipe_fd[1], "-", 1); @@ -124,6 +148,7 @@ BOOL SetEvent(HANDLE hEvent) { status = TRUE; } +#endif } LeaveCriticalSection(&cs); @@ -149,13 +174,23 @@ BOOL ResetEvent(HANDLE hEvent) while (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) { - length = read(event->pipe_fd[0], &length, 1); +#ifdef HAVE_EVENTFD_H + eventfd_t value; + do + { + length = eventfd_read(event->pipe_fd[0], &value); + } + while(length < 0 && errno == EINTR); + status = (length > 0) ? TRUE : FALSE; +#else + length = read(event->pipe_fd[0], &length, 1); if (length == 1) status = TRUE; if (length != 1) break; +#endif } }