libwinpr-thread: fix non-blocking internal pipe-based event on OS X
This commit is contained in:
parent
4fbec7633a
commit
2afcac7838
@ -83,6 +83,7 @@
|
||||
#include <winpr/debug.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
@ -95,14 +96,14 @@
|
||||
static pthread_once_t thread_initialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
static HANDLE_CLOSE_CB _ThreadHandleCloseCb;
|
||||
static wListDictionary *thread_list = NULL;
|
||||
static wListDictionary* thread_list = NULL;
|
||||
|
||||
static BOOL ThreadCloseHandle(HANDLE handle);
|
||||
static void cleanup_handle(void *obj);
|
||||
static void cleanup_handle(void* obj);
|
||||
|
||||
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_t* p1 = a;
|
||||
pthread_t* p2 = 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;
|
||||
void* rc = 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_THREAD* thread;
|
||||
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,9 +320,7 @@ 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");
|
||||
@ -326,12 +328,15 @@ HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize
|
||||
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_THREAD* thread;
|
||||
|
||||
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_THREAD* thread;
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user