libwinpr-thread: fix non-blocking internal pipe-based event on OS X
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 20 Nov 2014 16:48:02 +0000 (11:48 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 20 Nov 2014 16:48:02 +0000 (11:48 -0500)
winpr/libwinpr/thread/thread.c

index 461f576..1c56608 100644 (file)
@@ -83,6 +83,7 @@
 #include <winpr/debug.h>
 
 #include <errno.h>
+#include <fcntl.h>
 
 #include <winpr/collections.h>
 
 static pthread_once_t thread_initialized = PTHREAD_ONCE_INIT;
 
 static HANDLE_CLOSE_CB _ThreadHandleCloseCb;
-static wListDictionary *thread_list = NULL;
+static wListDictionarythread_list = NULL;
 
 static BOOL ThreadCloseHandle(HANDLE handle);
-static void cleanup_handle(void *obj);
+static void cleanup_handle(voidobj);
 
 static BOOL ThreadIsHandled(HANDLE handle)
 {
-       WINPR_THREAD *pThread = (WINPR_THREAD *)handle;
+       WINPR_THREAD* pThread = (WINPR_THREAD*) handle;
 
        if (!pThread || pThread->Type != HANDLE_TYPE_THREAD)
        {
@@ -113,7 +114,6 @@ static BOOL ThreadIsHandled(HANDLE handle)
        return TRUE;
 }
 
-
 static void ThreadInitialize(void)
 {
        _ThreadHandleCloseCb.IsHandled = ThreadIsHandled;
@@ -130,7 +130,7 @@ static void dump_thread(WINPR_THREAD* thread)
        WLog_DBG(TAG, "Called from:");
        msg = winpr_backtrace_symbols(stack, &used);
 
-       for (i=0; i<used; i++)
+       for (i = 0; i < used; i++)
                WLog_DBG(TAG, "[%d]: %s", i, msg[i]);
 
        free(msg);
@@ -138,26 +138,29 @@ static void dump_thread(WINPR_THREAD* thread)
        WLog_DBG(TAG, "Thread handle created still not closed!");
        msg = winpr_backtrace_symbols(thread->create_stack, &used);
 
-       for (i=0; i<used; i++)
+       for (i = 0; i < used; i++)
                WLog_DBG(TAG, "[%d]: %s", i, msg[i]);
 
        free(msg);
 
        if (thread->started)
+       {
                WLog_DBG(TAG, "Thread still running!");
+       }
        else if (!thread->exit_stack)
+       {
                WLog_DBG(TAG, "Thread suspended.");
+       }
        else
        {
                WLog_DBG(TAG, "Thread exited at:");
                msg = winpr_backtrace_symbols(thread->exit_stack, &used);
 
-               for (i=0; i<used; i++)
+               for (i = 0; i < used; i++)
                        WLog_DBG(TAG, "[%d]: %s", i, msg[i]);
 
                free(msg);
        }
-
 #endif
 }
 
@@ -180,7 +183,6 @@ static BOOL set_event(WINPR_THREAD *thread)
 
        status = (length == 0) ? TRUE : FALSE;
 #else
-
        if (WaitForSingleObject(thread, 0) != WAIT_OBJECT_0)
        {
                length = write(thread->pipe_fd[1], "-", 1);
@@ -192,7 +194,6 @@ static BOOL set_event(WINPR_THREAD *thread)
        {
                status = TRUE;
        }
-
 #endif
        return status;
 }
@@ -223,21 +224,21 @@ static BOOL reset_event(WINPR_THREAD *thread)
        return status;
 }
 
-static int thread_compare(void *a, void *b)
+static BOOL thread_compare(void* a, void* b)
 {
-       pthread_t *p1 = a;
-       pthread_t *p2 = b;
-       int rc = pthread_equal(*p1, *p2);
+       pthread_tp1 = a;
+       pthread_tp2 = b;
+       BOOL rc = pthread_equal(*p1, *p2);
        return rc;
 }
 
 /* Thread launcher function responsible for registering
  * cleanup handlers and calling pthread_exit, if not done
  * in thread function. */
-static void *thread_launcher(void *arg)
+static void* thread_launcher(void* arg)
 {
-       void *rc = NULL;
-       WINPR_THREAD *thread = (WINPR_THREAD *)arg;
+       voidrc = NULL;
+       WINPR_THREAD* thread = (WINPR_THREAD*) arg;
 
        if (!thread)
        {
@@ -246,7 +247,7 @@ static void *thread_launcher(void *arg)
        }
        else
        {
-               void *(*fkt)(void *) = (void *)thread->lpStartAddress;
+               void *(*fkt)(void*) = (void*) thread->lpStartAddress;
 
                if (!fkt)
                {
@@ -291,9 +292,10 @@ static void winpr_StartThread(WINPR_THREAD *thread)
 HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
                                        LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
 {
+       int flags;
        HANDLE handle;
-       WINPR_THREAD *thread;
-       thread = (WINPR_THREAD *) calloc(1, sizeof(WINPR_THREAD));
+       WINPR_THREADthread;
+       thread = (WINPR_THREAD*) calloc(1, sizeof(WINPR_THREAD));
 
        if (!thread)
                return NULL;
@@ -303,10 +305,12 @@ HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize
        thread->lpParameter = lpParameter;
        thread->lpStartAddress = lpStartAddress;
        thread->lpThreadAttributes = lpThreadAttributes;
+
 #if defined(WITH_DEBUG_THREADS)
        thread->create_stack = winpr_backtrace(20);
        dump_thread(thread);
 #endif
+       
 #ifdef HAVE_EVENTFD_H
        thread->pipe_fd[0] = eventfd(0, EFD_NONBLOCK);
 
@@ -316,22 +320,23 @@ HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize
                free(thread);
                return NULL;
        }
-
 #else
-
        if (pipe(thread->pipe_fd) < 0)
        {
                WLog_ERR(TAG, "failed to create thread");
                free(thread);
                return NULL;
        }
-
+       
+       flags = fcntl(thread->pipe_fd[0], F_GETFL);
+       fcntl(thread->pipe_fd[0], F_SETFL, flags | O_NONBLOCK);
 #endif
+       
        pthread_mutex_init(&thread->mutex, 0);
        WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD);
        handle = (HANDLE) thread;
 
-       if (NULL == thread_list)
+       if (!thread_list)
        {
                thread_list = ListDictionary_New(TRUE);
                thread_list->objectKey.fnObjectEquals = thread_compare;
@@ -347,7 +352,7 @@ HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize
 
 void cleanup_handle(void *obj)
 {
-       WINPR_THREAD *thread = (WINPR_THREAD *)obj;
+       WINPR_THREAD* thread = (WINPR_THREAD*) obj;
        int rc = pthread_mutex_destroy(&thread->mutex);
 
        if (rc)
@@ -377,7 +382,7 @@ void cleanup_handle(void *obj)
 
 BOOL ThreadCloseHandle(HANDLE handle)
 {
-       WINPR_THREAD *thread = (WINPR_THREAD *)handle;
+       WINPR_THREAD* thread = (WINPR_THREAD*) handle;
 
        if (!thread_list)
        {
@@ -401,7 +406,9 @@ BOOL ThreadCloseHandle(HANDLE handle)
                        pthread_detach(thread->thread);
                }
                else
+               {
                        cleanup_handle(thread);
+               }
 
                ListDictionary_Unlock(thread_list);
 
@@ -469,12 +476,12 @@ BOOL GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode)
 {
        ULONG Type;
        PVOID Object;
-       WINPR_THREAD *thread;
+       WINPR_THREADthread;
 
        if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
                return FALSE;
 
-       thread = (WINPR_THREAD *) Object;
+       thread = (WINPR_THREAD*) Object;
        *lpExitCode = thread->dwExitCode;
        return TRUE;
 }
@@ -484,7 +491,7 @@ HANDLE _GetCurrentThread(VOID)
        HANDLE hdl = NULL;
        pthread_t tid = pthread_self();
 
-       if (NULL == thread_list)
+       if (!thread_list)
        {
                WLog_ERR(TAG, "function called without existing thread list!");
 #if defined(WITH_DEBUG_THREADS)
@@ -522,7 +529,7 @@ DWORD ResumeThread(HANDLE hThread)
        if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
                return 0;
 
-       thread = (WINPR_THREAD *) Object;
+       thread = (WINPR_THREAD*) Object;
        pthread_mutex_lock(&thread->mutex);
 
        if (!thread->started)
@@ -549,12 +556,12 @@ BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode)
 {
        ULONG Type;
        PVOID Object;
-       WINPR_THREAD *thread;
+       WINPR_THREADthread;
 
        if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
                return 0;
 
-       thread = (WINPR_THREAD *) Object;
+       thread = (WINPR_THREAD*) Object;
        thread->exited = TRUE;
        thread->dwExitCode = dwExitCode;
        pthread_mutex_lock(&thread->mutex);
@@ -576,15 +583,19 @@ VOID DumpThreadHandles(void)
        WLog_DBG(TAG, "---------------- Called from ----------------------------");
        msg = winpr_backtrace_symbols(stack, &used);
 
-       for (i=0; i<used; i++)
+       for (i = 0; i < used; i++)
+       {
                WLog_DBG(TAG, "[%d]: %s", i, msg[i]);
+       }
 
        free(msg);
        winpr_backtrace_free(stack);
        WLog_DBG(TAG, "---------------- Start Dumping thread handles -----------");
 
        if (!thread_list)
+       {
                WLog_DBG(TAG, "All threads properly shut down and disposed of.");
+       }
        else
        {
                ULONG_PTR *keys = NULL;
@@ -592,19 +603,23 @@ VOID DumpThreadHandles(void)
                int x, count = ListDictionary_GetKeys(thread_list, &keys);
                WLog_DBG(TAG, "Dumping %d elements\n", count);
 
-               for (x=0; x<count; x++)
+               for (x = 0; x < count; x++)
                {
-                       WINPR_THREAD* thread = ListDictionary_GetItemValue(thread_list, (void*)keys[x]);
+                       WINPR_THREAD* thread = ListDictionary_GetItemValue(thread_list, (void*) keys[x]);
                        WLog_DBG(TAG, "Thread [%d] handle created still not closed!", x);
                        msg = winpr_backtrace_symbols(thread->create_stack, &used);
 
-                       for (i=0; i<used; i++)
+                       for (i = 0; i < used; i++)
+                       {
                                WLog_DBG(TAG, "[%d]: %s", i, msg[i]);
+                       }
 
                        free(msg);
 
                        if (thread->started)
+                       {
                                WLog_DBG(TAG, "Thread [%d] still running!",     x);
+                       }
                        else
                        {
                                WLog_DBG(TAG, "Thread [%d] exited at:", x);