xfreerdp: modify way to return thread exit code

This commit is contained in:
Marc-André Moreau 2013-04-02 14:51:12 -04:00
parent 5660b94b92
commit d13f89d359
8 changed files with 70 additions and 67 deletions

View File

@ -76,10 +76,6 @@
#include "xfreerdp.h"
HANDLE g_sem = NULL;
int g_thread_count = 0;
BYTE g_disconnect_reason = 0;
static long xv_port = 0;
static const size_t password_size = 512;
@ -1023,19 +1019,19 @@ void xf_window_free(xfInfo* xfi)
XFreeModifiermap(xfi->modifier_map);
xfi->modifier_map = 0;
if (xfi->gc != NULL)
if (xfi->gc)
{
XFreeGC(xfi->display, xfi->gc);
xfi->gc = 0;
}
if (xfi->gc_mono != NULL)
if (xfi->gc_mono)
{
XFreeGC(xfi->display, xfi->gc_mono);
xfi->gc_mono = 0;
}
if (xfi->window != NULL)
if (xfi->window)
{
xf_DestroyWindow(xfi, xfi->window);
xfi->window = NULL;
@ -1060,7 +1056,7 @@ void xf_window_free(xfInfo* xfi)
xfi->image = NULL;
}
if (context != NULL)
if (context)
{
cache_free(context->cache);
context->cache = NULL;
@ -1207,7 +1203,7 @@ void* xf_channels_thread(void* arg)
* @param instance - pointer to the rdp_freerdp structure that contains the session's settings
* @return A code from the enum XF_EXIT_CODE (0 if successful)
*/
int xfreerdp_run(freerdp* instance)
void* xf_thread(void* param)
{
int i;
int fds;
@ -1215,14 +1211,15 @@ int xfreerdp_run(freerdp* instance)
int max_fds;
int rcount;
int wcount;
int ret = 0;
BOOL status;
int exit_code;
void* rfds[32];
void* wfds[32];
fd_set rfds_set;
fd_set wfds_set;
freerdp* instance;
int fd_input_event;
HANDLE input_event = INVALID_HANDLE_VALUE;
HANDLE input_event;
int select_status;
BOOL async_update;
BOOL async_input;
@ -1235,6 +1232,11 @@ int xfreerdp_run(freerdp* instance)
rdpSettings* settings;
struct timeval timeout;
exit_code = 0;
input_event = NULL;
instance = (freerdp*) param;
ZeroMemory(rfds, sizeof(rfds));
ZeroMemory(wfds, sizeof(wfds));
ZeroMemory(&timeout, sizeof(struct timeval));
@ -1254,7 +1256,8 @@ int xfreerdp_run(freerdp* instance)
if (!status)
{
xf_free(xfi);
return XF_EXIT_CONN_FAILED;
exit_code = XF_EXIT_CONN_FAILED;
ExitThread(exit_code);
}
channels = instance->context->channels;
@ -1290,7 +1293,7 @@ int xfreerdp_run(freerdp* instance)
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get FreeRDP file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
exit_code = XF_EXIT_CONN_FAILED;
break;
}
}
@ -1300,7 +1303,7 @@ int xfreerdp_run(freerdp* instance)
if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get channel manager file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
exit_code = XF_EXIT_CONN_FAILED;
break;
}
}
@ -1310,7 +1313,7 @@ int xfreerdp_run(freerdp* instance)
if (xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
{
fprintf(stderr, "Failed to get xfreerdp file descriptor\n");
ret = XF_EXIT_CONN_FAILED;
exit_code = XF_EXIT_CONN_FAILED;
break;
}
}
@ -1441,8 +1444,8 @@ int xfreerdp_run(freerdp* instance)
}
}
if (!ret)
ret = freerdp_error_info(instance);
if (!exit_code)
exit_code = freerdp_error_info(instance);
freerdp_channels_close(channels, instance);
freerdp_channels_free(channels);
@ -1450,27 +1453,12 @@ int xfreerdp_run(freerdp* instance)
gdi_free(instance);
xf_free(xfi);
return ret;
ExitThread(exit_code);
}
void* xf_thread_func(void* param)
DWORD xf_exit_code_from_disconnect_reason(DWORD reason)
{
freerdp* instance = (freerdp*) param;
g_disconnect_reason = xfreerdp_run(instance);
g_thread_count--;
if (g_thread_count < 1)
ReleaseSemaphore(g_sem, 1, NULL);
pthread_exit(NULL);
}
BYTE xf_exit_code_from_disconnect_reason(UINT32 reason)
{
if (reason == 0 ||
(reason >= XF_EXIT_PARSE_ARGUMENTS && reason <= XF_EXIT_CONN_FAILED))
if (reason == 0 || (reason >= XF_EXIT_PARSE_ARGUMENTS && reason <= XF_EXIT_CONN_FAILED))
return reason;
/* License error set */

View File

@ -34,8 +34,8 @@ int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type);
int xf_receive_channel_data(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size);
BYTE xf_exit_code_from_disconnect_reason(UINT32 reason);
DWORD xf_exit_code_from_disconnect_reason(DWORD reason);
void* xf_thread_func(void* param);
void* xf_thread(void* param);
#endif /* __XF_INTERFACE_H */

View File

@ -40,13 +40,10 @@
#include "xfreerdp.h"
extern HANDLE g_sem;
extern int g_thread_count;
extern BYTE g_disconnect_reason;
int main(int argc, char* argv[])
{
pthread_t thread;
HANDLE thread;
DWORD dwExitCode;
freerdp* instance;
freerdp_handle_signals();
@ -55,8 +52,6 @@ int main(int argc, char* argv[])
freerdp_channels_global_init();
g_sem = CreateSemaphore(NULL, 0, 1, NULL);
instance = freerdp_new();
instance->PreConnect = xf_pre_connect;
instance->PostConnect = xf_post_connect;
@ -74,21 +69,16 @@ int main(int argc, char* argv[])
instance->context->argv = argv;
instance->settings->SoftwareGdi = FALSE;
g_thread_count++;
pthread_create(&thread, 0, xf_thread_func, instance);
thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread, (void*) instance, 0, NULL);
while (g_thread_count > 0)
{
WaitForSingleObject(g_sem, INFINITE);
}
WaitForSingleObject(thread, INFINITE);
pthread_join(thread, NULL);
pthread_detach(thread);
GetExitCodeThread(thread, &dwExitCode);
freerdp_context_free(instance);
freerdp_free(instance);
freerdp_channels_global_uninit();
return xf_exit_code_from_disconnect_reason(g_disconnect_reason);
return xf_exit_code_from_disconnect_reason(dwExitCode);
}

View File

@ -20,23 +20,14 @@
#ifndef WINPR_SPEC_H
#define WINPR_SPEC_H
#include <winpr/platform.h>
#ifdef _WIN32
#include <specstrings.h>
#else
#if defined(__x86_64) && \
!(defined(_X86_) || defined(__i386__) || defined(_IA64_))
#if !defined(_AMD64_)
#define _AMD64_
#endif
#endif /* _AMD64_ */
#ifdef _AMD64_
#define _WIN64
#endif
#ifndef DECLSPEC_ALIGN
#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(MIDL_PASS)
#define DECLSPEC_ALIGN(x) __declspec(align(x))
@ -47,7 +38,7 @@
#endif
#endif /* DECLSPEC_ALIGN */
#ifdef _WIN64
#ifdef _M_AMD64
#define MEMORY_ALLOCATION_ALIGNMENT 16
#else
#define MEMORY_ALLOCATION_ALIGNMENT 8
@ -55,7 +46,19 @@
#define DUMMYSTRUCTNAME s
#ifdef __GNUC__
#ifndef __declspec
#define __declspec(e) __attribute__((e))
#endif
#endif
#ifndef DECLSPEC_NORETURN
#if (defined(__GNUC__) || defined(_MSC_VER))
#define DECLSPEC_NORETURN __declspec(noreturn)
#else
#define DECLSPEC_NORETURN
#endif
#endif /* DECLSPEC_NORETURN */
#endif

View File

@ -23,6 +23,7 @@
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
#include <winpr/spec.h>
#include <winpr/handle.h>
#ifndef _WIN32
@ -105,7 +106,7 @@ WINPR_API BOOL CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApplicationName, LP
#define CreateProcessAsUser CreateProcessAsUserA
#endif
WINPR_API VOID ExitProcess(UINT uExitCode);
DECLSPEC_NORETURN WINPR_API VOID ExitProcess(UINT uExitCode);
WINPR_API HANDLE _GetCurrentProcess(VOID);
WINPR_API DWORD GetCurrentProcessId(VOID);
@ -123,7 +124,8 @@ WINPR_API HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T d
WINPR_API HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
WINPR_API VOID ExitThread(DWORD dwExitCode);
DECLSPEC_NORETURN WINPR_API VOID ExitThread(DWORD dwExitCode);
WINPR_API BOOL GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode);
WINPR_API HANDLE _GetCurrentThread(VOID);
WINPR_API DWORD GetCurrentThreadId(VOID);

View File

@ -64,6 +64,9 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
if (status != 0)
fprintf(stderr, "WaitForSingleObject: pthread_join failure: %d\n", status);
if (thread_status)
thread->dwExitCode = ((DWORD*) thread_status);
}
else if (Type == HANDLE_TYPE_MUTEX)
{

View File

@ -128,6 +128,22 @@ VOID ExitThread(DWORD dwExitCode)
pthread_exit((void*) dwExitCode);
}
BOOL GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode)
{
ULONG Type;
PVOID Object;
WINPR_THREAD* thread;
if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
return FALSE;
thread = (WINPR_THREAD*) Object;
*lpExitCode = thread->dwExitCode;
return TRUE;
}
HANDLE _GetCurrentThread(VOID)
{
return NULL;

View File

@ -31,6 +31,7 @@ typedef void *(*pthread_start_routine)(void*);
struct winpr_thread
{
BOOL started;
DWORD dwExitCode;
pthread_t thread;
SIZE_T dwStackSize;
LPVOID lpParameter;