if (status != 0)
{
WLog_ERR(TAG, "pthread_join failure: [%d] %s",
- status, strerror(status));
+ status, strerror(status));
pthread_mutex_unlock(&thread->mutex);
return WAIT_FAILED;
}
return WAIT_OBJECT_0;
}
-static HANDLE_OPS ops = {
- ThreadIsHandled,
- ThreadCloseHandle,
- ThreadGetFd,
- ThreadCleanupHandle
+static HANDLE_OPS ops =
+{
+ ThreadIsHandled,
+ ThreadCloseHandle,
+ ThreadGetFd,
+ ThreadCleanupHandle
};
free(msg);
}
+
#endif
}
* TODO: implement thread suspend/resume using pthreads
* http://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition
*/
-static BOOL set_event(WINPR_THREAD *thread)
+static BOOL set_event(WINPR_THREAD* thread)
{
int length;
BOOL status = FALSE;
status = (length == 0) ? TRUE : FALSE;
#else
+
if (WaitForSingleObject(thread, 0) != WAIT_OBJECT_0)
{
length = write(thread->pipe_fd[1], "-", 1);
{
status = TRUE;
}
+
#endif
return status;
}
-static BOOL reset_event(WINPR_THREAD *thread)
+static BOOL reset_event(WINPR_THREAD* thread)
{
int length;
BOOL status = FALSE;
* in thread function. */
static void* thread_launcher(void* arg)
{
- DWORD res = -1;
+ DWORD res = 1;
void* rc = NULL;
WINPR_THREAD* thread = (WINPR_THREAD*) arg;
- void *(*fkt)(void*);
+ typedef void* (*fkt_t)(void*);
+ fkt_t fkt;
if (!thread)
{
goto exit;
}
- if (!(fkt = (void*) thread->lpStartAddress))
+ if (!(fkt = (fkt_t)thread->lpStartAddress))
{
WLog_ERR(TAG, "Thread function argument is %p", fkt);
goto exit;
goto exit;
}
}
+
if (pthread_mutex_unlock(&thread->threadIsReadyMutex))
goto exit;
assert(ListDictionary_Contains(thread_list, &thread->thread));
-
rc = fkt(thread->lpParameter);
-
exit:
if (thread)
thread->dwExitCode = (DWORD)(size_t)rc;
set_event(thread);
-
res = thread->dwExitCode;
+
if (thread->detached || !thread->started)
cleanup_handle(thread);
}
+
return rc;
}
-static BOOL winpr_StartThread(WINPR_THREAD *thread)
+static BOOL winpr_StartThread(WINPR_THREAD* thread)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
if (pthread_create(&thread->thread, &attr, thread_launcher, thread))
goto error;
-
if (pthread_mutex_lock(&thread->threadIsReadyMutex))
goto error;
pthread_mutex_unlock(&thread->threadIsReadyMutex);
goto error;
}
+
if (pthread_cond_signal(&thread->threadIsReady) != 0)
{
WLog_ERR(TAG, "failed to signal the thread was ready");
pthread_mutex_unlock(&thread->threadIsReadyMutex);
goto error;
}
+
if (pthread_mutex_unlock(&thread->threadIsReadyMutex))
goto error;
pthread_attr_destroy(&attr);
dump_thread(thread);
return TRUE;
-
error:
pthread_attr_destroy(&attr);
return FALSE;
}
-HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
+HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ SIZE_T dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter,
+ DWORD dwCreationFlags, LPDWORD lpThreadId)
{
HANDLE handle;
WINPR_THREAD* thread;
-
thread = (WINPR_THREAD*) calloc(1, sizeof(WINPR_THREAD));
if (!thread)
thread->lpStartAddress = lpStartAddress;
thread->lpThreadAttributes = lpThreadAttributes;
thread->ops = &ops;
-
#if defined(WITH_DEBUG_THREADS)
thread->create_stack = winpr_backtrace(20);
dump_thread(thread);
#endif
thread->pipe_fd[0] = -1;
thread->pipe_fd[1] = -1;
-
#ifdef HAVE_EVENTFD_H
thread->pipe_fd[0] = eventfd(0, EFD_NONBLOCK);
WLog_ERR(TAG, "failed to create thread pipe fd 0");
goto error_pipefd0;
}
+
#else
+
if (pipe(thread->pipe_fd) < 0)
{
WLog_ERR(TAG, "failed to create thread pipe");
goto error_pipefd0;
}
-
+
{
int flags = fcntl(thread->pipe_fd[0], F_GETFL);
fcntl(thread->pipe_fd[0], F_SETFL, flags | O_NONBLOCK);
}
+
#endif
-
- if(pthread_mutex_init(&thread->mutex, 0) != 0)
+
+ if (pthread_mutex_init(&thread->mutex, 0) != 0)
{
WLog_ERR(TAG, "failed to initialize thread mutex");
goto error_mutex;
if (!thread_list)
{
thread_list = ListDictionary_New(TRUE);
+
if (!thread_list)
{
WLog_ERR(TAG, "Couldn't create global thread list");
goto error_thread_list;
}
+
thread_list->objectKey.fnObjectEquals = thread_compare;
}
}
return handle;
-
error_thread_list:
pthread_cond_destroy(&thread->threadIsReady);
error_thread_ready:
error_thread_ready_mutex:
pthread_mutex_destroy(&thread->mutex);
error_mutex:
+
if (thread->pipe_fd[1] >= 0)
close(thread->pipe_fd[1]);
+
if (thread->pipe_fd[0] >= 0)
close(thread->pipe_fd[0]);
+
error_pipefd0:
free(thread);
return NULL;
}
-void cleanup_handle(void *obj)
+void cleanup_handle(void* obj)
{
int rc;
WINPR_THREAD* thread = (WINPR_THREAD*) obj;
-
-
rc = pthread_cond_destroy(&thread->threadIsReady);
+
if (rc)
WLog_ERR(TAG, "failed to destroy a condition variable [%d] %s (%d)",
- rc, strerror(errno), errno);
+ rc, strerror(errno), errno);
rc = pthread_mutex_destroy(&thread->threadIsReadyMutex);
+
if (rc)
WLog_ERR(TAG, "failed to destroy a condition variable mutex [%d] %s (%d)",
- rc, strerror(errno), errno);
+ rc, strerror(errno), errno);
rc = pthread_mutex_destroy(&thread->mutex);
+
if (rc)
WLog_ERR(TAG, "failed to destroy mutex [%d] %s (%d)",
- rc, strerror(errno), errno);
+ rc, strerror(errno), errno);
if (thread->pipe_fd[0] >= 0)
close(thread->pipe_fd[0]);
return TRUE;
}
-HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
+HANDLE CreateRemoteThread(HANDLE hProcess,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter,
+ DWORD dwCreationFlags, LPDWORD lpThreadId)
{
WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
else
{
WINPR_THREAD* thread;
-
ListDictionary_Lock(thread_list);
thread = ListDictionary_GetItemValue(thread_list, &tid);
-
assert(thread);
thread->exited = TRUE;
thread->dwExitCode = dwExitCode;
#endif
ListDictionary_Unlock(thread_list);
set_event(thread);
-
rc = thread->dwExitCode;
+
if (thread->detached || !thread->started)
cleanup_handle(thread);
- pthread_exit((void*) (size_t) rc);
+ pthread_exit((void*)(size_t) rc);
}
}
{
pthread_t tid;
tid = pthread_self();
-
/* Since pthread_t can be 64-bits on some systems, take just the */
/* lower 32-bits of it for the thread ID returned by this function. */
return (DWORD)tid & 0xffffffffUL;
WINPR_THREAD* thread;
if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
- return (DWORD)-1;
+ return (DWORD) - 1;
thread = (WINPR_THREAD*) Object;
+
if (pthread_mutex_lock(&thread->mutex))
- return (DWORD)-1;
+ return (DWORD) - 1;
if (!thread->started)
{
if (!winpr_StartThread(thread))
{
pthread_mutex_unlock(&thread->mutex);
- return (DWORD)-1;
+ return (DWORD) - 1;
}
}
else
WLog_WARN(TAG, "Thread already started!");
if (pthread_mutex_unlock(&thread->mutex))
- return (DWORD)-1;
+ return (DWORD) - 1;
return 0;
}
{
WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return (DWORD)-1;
+ return (DWORD) - 1;
}
BOOL SwitchToThread(VOID)
thread = (WINPR_THREAD*) Object;
thread->exited = TRUE;
thread->dwExitCode = dwExitCode;
+
if (pthread_mutex_lock(&thread->mutex))
return FALSE;
#else
WLog_ERR(TAG, "Function not supported on this platform!");
#endif
+
if (pthread_mutex_unlock(&thread->mutex))
return FALSE;
}
else
{
- ULONG_PTR *keys = NULL;
+ ULONG_PTR* keys = NULL;
ListDictionary_Lock(thread_list);
int x, count = ListDictionary_GetKeys(thread_list, &keys);
WLog_DBG(TAG, "Dumping %d elements", count);
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);
WLog_DBG(TAG, "Thread [%d] exited at:", x);
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);
}
free(keys);
-
ListDictionary_Unlock(thread_list);
}