set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR")
+if(BUILD_TESTING)
+ add_subdirectory(test)
+endif()
WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT);
handle = (HANDLE) event;
+
+ if (bInitialState)
+ SetEvent(handle);
}
if (!cs.LockSemaphore)
--- /dev/null
+TestSynch
+TestSynch.c
+
--- /dev/null
+
+set(MODULE_NAME "TestSynch")
+set(MODULE_PREFIX "TEST_SYNCH")
+
+set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
+
+set(${MODULE_PREFIX}_TESTS
+ TestSynchEvent.c
+ TestSynchMutex.c
+ TestSynchSemaphore.c
+ TestSynchWaitableTimer.c)
+
+create_test_sourcelist(${MODULE_PREFIX}_SRCS
+ ${${MODULE_PREFIX}_DRIVER}
+ ${${MODULE_PREFIX}_TESTS})
+
+add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
+
+set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
+ MONOLITHIC ${MONOLITHIC_BUILD}
+ MODULE winpr
+ MODULES winpr-synch)
+
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
+
+set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
+
+foreach(test ${${MODULE_PREFIX}_TESTS})
+ get_filename_component(TestName ${test} NAME_WE)
+ add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
+endforeach()
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
--- /dev/null
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+int TestSynchEvent(int argc, char* argv[])
+{
+ HANDLE event;
+
+ event = CreateEvent(NULL, TRUE, TRUE, NULL);
+
+ if (!event)
+ {
+ printf("CreateEvent failure\n");
+ return -1;
+ }
+
+ if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0)
+ {
+ printf("WaitForSingleObject(event, INFINITE) failure\n");
+ return -1;
+ }
+
+ ResetEvent(event);
+
+ if (WaitForSingleObject(event, 0) != WAIT_TIMEOUT)
+ {
+ printf("WaitForSingleObject(event, 0) failure\n");
+ return -1;
+ }
+
+ SetEvent(event);
+
+ if (WaitForSingleObject(event, 0) != WAIT_OBJECT_0)
+ {
+ printf("WaitForSingleObject(event, 0) failure\n");
+ return -1;
+ }
+
+ CloseHandle(event);
+
+ return 0;
+}
--- /dev/null
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+int TestSynchMutex(int argc, char* argv[])
+{
+ HANDLE mutex;
+
+ mutex = CreateMutex(NULL, FALSE, NULL);
+
+ if (!mutex)
+ {
+ printf("CreateMutex failure\n");
+ return -1;
+ }
+
+ CloseHandle(mutex);
+
+ return 0;
+}
+
--- /dev/null
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+int TestSynchSemaphore(int argc, char* argv[])
+{
+ HANDLE semaphore;
+
+ semaphore = CreateSemaphore(NULL, 0, 1, NULL);
+
+ if (!semaphore)
+ {
+ printf("CreateSemaphore failure\n");
+ return -1;
+ }
+
+ CloseHandle(semaphore);
+
+ return 0;
+}
+
--- /dev/null
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+
+int TestSynchWaitableTimer(int argc, char* argv[])
+{
+ HANDLE timer;
+ LONG period;
+ LARGE_INTEGER due;
+
+ timer = CreateWaitableTimer(NULL, TRUE, NULL);
+
+ if (!timer)
+ {
+ printf("CreateWaitableTimer failure\n");
+ return -1;
+ }
+
+ due.QuadPart = -15000000LL; /* 1.5 seconds */
+
+ if (!SetWaitableTimer(timer, &due, 0, NULL, NULL, 0))
+ {
+ printf("SetWaitableTimer failure\n");
+ return -1;
+ }
+
+ if (WaitForSingleObject(timer, INFINITE) != WAIT_OBJECT_0)
+ {
+ printf("WaitForSingleObject(timer, INFINITE) failure\n");
+ return -1;
+ }
+
+ printf("Timer Signaled\n");
+
+ if (WaitForSingleObject(timer, 2000) != WAIT_TIMEOUT)
+ {
+ printf("WaitForSingleObject(timer, 2000) failure\n");
+ return -1;
+ }
+
+ due.QuadPart = 0;
+
+ period = 1200; /* 1.2 seconds */
+
+ if (!SetWaitableTimer(timer, &due, period, NULL, NULL, 0))
+ {
+ printf("SetWaitableTimer failure\n");
+ return -1;
+ }
+
+ if (WaitForSingleObject(timer, INFINITE) != WAIT_OBJECT_0)
+ {
+ printf("WaitForSingleObject(timer, INFINITE) failure\n");
+ return -1;
+ }
+
+ printf("Timer Signaled\n");
+
+ if (WaitForMultipleObjects(1, &timer, FALSE, INFINITE) != WAIT_OBJECT_0)
+ {
+ printf("WaitForMultipleObjects(timer, INFINITE) failure\n");
+ return -1;
+ }
+
+ printf("Timer Signaled\n");
+
+ CloseHandle(timer);
+
+ return 0;
+}
+
#ifdef __linux__
ZeroMemory(&(timer->timeout), sizeof(struct itimerspec));
- if (lpDueTime < 0)
+ if (lpDueTime->QuadPart < 0)
{
LONGLONG due = lpDueTime->QuadPart * (-1);
seconds = (due / 10000000);
nanoseconds = ((due % 10000000) * 100);
}
+ else if (lpDueTime->QuadPart == 0)
+ {
+ seconds = nanoseconds = 0;
+ }
else
{
printf("SetWaitableTimer: implement absolute time\n");
+ return FALSE;
}
- timer->timeout.it_value.tv_sec = seconds; /* seconds */
- timer->timeout.it_value.tv_nsec = nanoseconds; /* nanoseconds */
-
if (lPeriod > 0)
{
timer->timeout.it_interval.tv_sec = (lPeriod / 1000); /* seconds */
timer->timeout.it_interval.tv_nsec = ((lPeriod % 1000) * 1000000); /* nanoseconds */
}
+ if (lpDueTime->QuadPart != 0)
+ {
+ timer->timeout.it_value.tv_sec = seconds; /* seconds */
+ timer->timeout.it_value.tv_nsec = nanoseconds; /* nanoseconds */
+ }
+ else
+ {
+ timer->timeout.it_value.tv_sec = timer->timeout.it_interval.tv_sec; /* seconds */
+ timer->timeout.it_value.tv_nsec = timer->timeout.it_interval.tv_nsec; /* nanoseconds */
+ }
+
status = timerfd_settime(timer->fd, 0, &(timer->timeout), NULL);
if (status)
+ {
+ printf("SetWaitableTimer timerfd_settime failure: %d\n", status);
return FALSE;
+ }
#endif
return TRUE;
if (timer->fd != -1)
{
int status;
- int length;
fd_set rfds;
+ UINT64 expirations;
struct timeval timeout;
FD_ZERO(&rfds);
if (status != 1)
return WAIT_TIMEOUT;
+
+ status = read(timer->fd, (void*) &expirations, sizeof(UINT64));
+
+ if (status != 8)
+ return WAIT_TIMEOUT;
}
else
{
{
if (Type == HANDLE_TYPE_SEMAPHORE)
{
- int length = read(fd, &length, 1);
+ int length;
+
+ length = read(fd, &length, 1);
if (length != 1)
return WAIT_FAILED;
}
+ else if (Type == HANDLE_TYPE_TIMER)
+ {
+ int length;
+ UINT64 expirations;
+
+ length = read(fd, (void*) &expirations, sizeof(UINT64));
+
+ if (length != 8)
+ return WAIT_FAILED;
+ }
return (WAIT_OBJECT_0 + index);
}