Merge pull request #2706 from nfedera/nf-fix-reset-event

winpr/synch: fix ResetEvent & improve CTest
This commit is contained in:
Hardening 2015-06-18 09:28:31 +02:00
commit c8731eaa2c
2 changed files with 72 additions and 27 deletions

View File

@ -37,9 +37,10 @@
#ifdef HAVE_EVENTFD_H
#include <sys/eventfd.h>
#include <errno.h>
#endif
#include <errno.h>
#include "../handle/handle.h"
#include "../pipe/pipe.h"
@ -219,7 +220,6 @@ BOOL SetEvent(HANDLE hEvent)
status = (length == 0) ? TRUE : FALSE;
#else
if (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
{
length = write(event->pipe_fd[1], "-", 1);
@ -243,36 +243,29 @@ BOOL ResetEvent(HANDLE hEvent)
ULONG Type;
PVOID Object;
int length;
BOOL status;
BOOL status = TRUE;
WINPR_EVENT* event;
status = FALSE;
if (winpr_Handle_GetInfo(hEvent, &Type, &Object))
if (!winpr_Handle_GetInfo(hEvent, &Type, &Object))
return FALSE;
event = (WINPR_EVENT*) Object;
while (status && WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
{
event = (WINPR_EVENT*) Object;
while (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
do
{
#ifdef HAVE_EVENTFD_H
eventfd_t value;
do
{
length = eventfd_read(event->pipe_fd[0], &value);
}
while ((length < 0) && (errno == EINTR));
if ((length > 0) && (!status))
status = TRUE;
length = eventfd_read(event->pipe_fd[0], &value);
#else
length = read(event->pipe_fd[0], &length, 1);
if ((length == 1) && (!status))
status = TRUE;
#endif
}
while ((length < 0) && (errno == EINTR));
if (length < 0)
status = FALSE;
}
return status;

View File

@ -5,6 +5,19 @@
int TestSynchEvent(int argc, char* argv[])
{
HANDLE event;
int i;
if (ResetEvent(NULL))
{
printf("ResetEvent(NULL) unexpectedly succeeded\n");
return -1;
}
if (SetEvent(NULL))
{
printf("SetEvent(NULL) unexpectedly succeeded\n");
return -1;
}
event = CreateEvent(NULL, TRUE, TRUE, NULL);
@ -16,23 +29,62 @@ int TestSynchEvent(int argc, char* argv[])
if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0)
{
printf("WaitForSingleObject(event, INFINITE) failure\n");
printf("WaitForSingleObject failure 1\n");
return -1;
}
ResetEvent(event);
if (!ResetEvent(event))
{
printf("ResetEvent failure with signaled event object\n");
return -1;
}
if (WaitForSingleObject(event, 0) != WAIT_TIMEOUT)
{
printf("WaitForSingleObject(event, 0) failure\n");
printf("WaitForSingleObject failure 2\n");
return -1;
}
SetEvent(event);
if (!ResetEvent(event))
{
/* Note: ResetEvent must also succeed if event is currently nonsignaled */
printf("ResetEvent failure with nonsignaled event object\n");
return -1;
}
if (!SetEvent(event))
{
printf("SetEvent failure with nonsignaled event object\n");
return -1;
}
if (WaitForSingleObject(event, 0) != WAIT_OBJECT_0)
{
printf("WaitForSingleObject(event, 0) failure\n");
printf("WaitForSingleObject failure 3\n");
return -1;
}
for (i = 0; i < 10000; i++)
{
if (!SetEvent(event))
{
printf("SetEvent failure with signaled event object (i = %d)\n", i);
return -1;
}
}
if (!ResetEvent(event))
{
printf("ResetEvent failure after multiple SetEvent calls\n");
return -1;
}
/* Independent of the amount of the previous SetEvent calls, a single
ResetEvent must be sufficient to get into nonsignaled state */
if (WaitForSingleObject(event, 0) != WAIT_TIMEOUT)
{
printf("WaitForSingleObject failure 4\n");
return -1;
}