diff --git a/client/iOS/Misc/Utils.m b/client/iOS/Misc/Utils.m index 58572cd76..ed121c57a 100644 --- a/client/iOS/Misc/Utils.m +++ b/client/iOS/Misc/Utils.m @@ -12,6 +12,7 @@ #import "TSXAdditions.h" #import +#import #import "config.h" #include diff --git a/client/iOS/Views/BlockAlertView.m b/client/iOS/Views/BlockAlertView.m index 2a7270047..8b938286c 100755 --- a/client/iOS/Views/BlockAlertView.m +++ b/client/iOS/Views/BlockAlertView.m @@ -279,10 +279,10 @@ static UIFont *buttonFont = nil; button.frame = CGRectMake(xOffset, _height, width, kAlertButtonHeight); button.titleLabel.font = buttonFont; if (IOS_LESS_THAN_6) { -#pragma clan diagnostic push +#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" button.titleLabel.minimumFontSize = 10; -#pragma clan diagnostic pop +#pragma clang diagnostic pop } else { button.titleLabel.adjustsFontSizeToFitWidth = YES; diff --git a/config.h.in b/config.h.in index 839ec0da0..043592ca6 100755 --- a/config.h.in +++ b/config.h.in @@ -24,6 +24,7 @@ #cmakedefine HAVE_TIMERFD_H #cmakedefine HAVE_TM_GMTOFF #cmakedefine HAVE_AIO_H +#cmakedefine HAVE_PTHREAD_GNU_EXT /* Options */ diff --git a/winpr/libwinpr/synch/test/CMakeLists.txt b/winpr/libwinpr/synch/test/CMakeLists.txt index a00169ccd..b3a774ce6 100644 --- a/winpr/libwinpr/synch/test/CMakeLists.txt +++ b/winpr/libwinpr/synch/test/CMakeLists.txt @@ -9,6 +9,7 @@ set(${MODULE_PREFIX}_TESTS TestSynchMutex.c TestSynchCritical.c TestSynchSemaphore.c + TestSynchThread.c TestSynchWaitableTimer.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS diff --git a/winpr/libwinpr/synch/test/TestSynchMutex.c b/winpr/libwinpr/synch/test/TestSynchMutex.c index 6d2a5df43..22983a6d0 100644 --- a/winpr/libwinpr/synch/test/TestSynchMutex.c +++ b/winpr/libwinpr/synch/test/TestSynchMutex.c @@ -4,16 +4,48 @@ int TestSynchMutex(int argc, char* argv[]) { + DWORD rc; HANDLE mutex; mutex = CreateMutex(NULL, FALSE, NULL); - if (!mutex) { printf("CreateMutex failure\n"); return -1; } + /* Lock the mutex */ + rc = WaitForSingleObject(mutex, INFINITE); + if (WAIT_OBJECT_0 != rc) + { + printf("WaitForSingleObject on mutex failed with %d\n", rc); + return -2; + } + + /* TryLock should now fail. */ + rc = WaitForSingleObject(mutex, 0); + if (WAIT_TIMEOUT != rc) + { + printf("Timed WaitForSingleObject on locked mutex failed with %d\n", rc); + return -3; + } + + /* Unlock the mutex */ + rc = ReleaseMutex(mutex); + if (!rc) + { + printf("ReleaseMutex failed.\n"); + return -4; + } + + /* TryLock should now succeed. */ + rc = WaitForSingleObject(mutex, 0); + if (WAIT_OBJECT_0 != rc) + { + printf("Timed WaitForSingleObject on free mutex failed with %d\n", rc); + return -5; + } + CloseHandle(mutex); return 0; diff --git a/winpr/libwinpr/synch/test/TestSynchThread.c b/winpr/libwinpr/synch/test/TestSynchThread.c new file mode 100644 index 000000000..cb8e6d2ae --- /dev/null +++ b/winpr/libwinpr/synch/test/TestSynchThread.c @@ -0,0 +1,55 @@ + +#include +#include +#include + +static void *test_thread(void *arg) +{ + Sleep(1000); + + ExitThread(0); + return NULL; +} + +int TestSynchThread(int argc, char* argv[]) +{ + DWORD rc; + HANDLE thread; + + thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread, + NULL, 0, NULL); + if (!thread) + { + printf("CreateThread failure\n"); + return -1; + } + + /* TryJoin should now fail. */ + rc = WaitForSingleObject(thread, 0); + if (WAIT_TIMEOUT != rc) + { + printf("Timed WaitForSingleObject on running thread failed with %d\n", rc); + return -3; + } + + /* Join the thread */ + rc = WaitForSingleObject(thread, INFINITE); + if (WAIT_OBJECT_0 != rc) + { + printf("WaitForSingleObject on thread failed with %d\n", rc); + return -2; + } + + /* TimedJoin should now succeed. */ + rc = WaitForSingleObject(thread, 0); + if (WAIT_OBJECT_0 != rc) + { + printf("Timed WaitForSingleObject on dead thread failed with %d\n", rc); + return -5; + } + + CloseHandle(thread); + + return 0; +} + diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 47ca366c2..15840916a 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -86,10 +86,20 @@ int clock_gettime(int clk_id, struct timespec *t) */ #if !defined(HAVE_PTHREAD_GNU_EXT) #include + +static long long ts_difftime(struct timespec *o, + struct timespec *n) +{ + long long old = o->tv_sec * 1000000000LL + o->tv_nsec; + long long new = n->tv_sec * 1000000000LL + n->tv_nsec; + + return new - old; +} + static int pthread_timedjoin_np(pthread_t td, void **res, struct timespec *timeout) { - struct timeval timenow; + struct timespec timenow; struct timespec sleepytime; /* This is just to avoid a completely busy wait */ sleepytime.tv_sec = 0; @@ -101,11 +111,10 @@ static int pthread_timedjoin_np(pthread_t td, void **res, return pthread_join(td, res); nanosleep(&sleepytime, NULL); - - gettimeofday(&timenow, NULL); + + clock_gettime(CLOCK_MONOTONIC, &timenow); - if (timenow.tv_sec >= timeout->tv_sec && - (timenow.tv_usec * 1000) >= timeout->tv_nsec) + if (ts_difftime(timeout, &timenow) >= 0) { return ETIMEDOUT; } @@ -117,7 +126,7 @@ static int pthread_timedjoin_np(pthread_t td, void **res, static int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *timeout) { - struct timeval timenow; + struct timespec timenow; struct timespec sleepytime; int retcode; @@ -127,10 +136,9 @@ static int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) { - gettimeofday (&timenow, NULL); + clock_gettime(CLOCK_MONOTONIC, &timenow); - if (timenow.tv_sec >= timeout->tv_sec && - (timenow.tv_usec * 1000) >= timeout->tv_nsec) + if (ts_difftime(timeout, &timenow) >= 0) { return ETIMEDOUT; } @@ -172,7 +180,6 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) if (thread->started) { -#ifdef __linux__ if (dwMilliseconds != INFINITE) { struct timespec timeout; @@ -182,7 +189,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) if (dwMilliseconds == 0) dwMilliseconds ++; - clock_gettime(CLOCK_REALTIME, &timeout); + clock_gettime(CLOCK_MONOTONIC, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); @@ -191,7 +198,6 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) return WAIT_TIMEOUT; } else -#endif status = pthread_join(thread->thread, &thread_status); if (status != 0) @@ -223,13 +229,12 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) mutex = (WINPR_MUTEX*) Object; -#ifdef __linux__ if (dwMilliseconds != INFINITE) { int status; struct timespec timeout; - clock_gettime(CLOCK_REALTIME, &timeout); + clock_gettime(CLOCK_MONOTONIC, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_mutex_timedlock(&mutex->mutex, &timeout); @@ -238,7 +243,6 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) return WAIT_TIMEOUT; } else -#endif pthread_mutex_lock(&mutex->mutex); } else if (Type == HANDLE_TYPE_EVENT)