Merge pull request #949 from hardening/eventfd

Add support for eventfd
This commit is contained in:
Marc-André Moreau 2013-02-02 13:30:33 -08:00
commit a00ac1f689
3 changed files with 39 additions and 3 deletions

View File

@ -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")

View File

@ -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

View File

@ -35,6 +35,12 @@
#include <unistd.h>
#endif
#ifdef HAVE_EVENTFD_H
#include <sys/eventfd.h>
#include <errno.h>
#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
}
}