Commit 9e2fb411 authored by Arkadiusz Hiler's avatar Arkadiusz Hiler Committed by Alexandre Julliard

msvcrt: Use trampoline for _beginthreadex().

This way we can call _endthreadex() at the end as stated in the documentation. Signed-off-by: 's avatarArkadiusz Hiler <ahiler@codeweavers.com> Signed-off-by: 's avatarPiotr Caban <piotr@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 80678c43
......@@ -27,7 +27,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
typedef struct {
HANDLE thread;
union {
_beginthread_start_routine_t start_address;
_beginthreadex_start_routine_t start_address_ex;
};
void *arglist;
} _beginthread_trampoline_t;
......@@ -148,6 +151,22 @@ uintptr_t CDECL _beginthread(
}
/*********************************************************************
* _beginthreadex_trampoline
*/
static DWORD CALLBACK _beginthreadex_trampoline(LPVOID arg)
{
unsigned int retval;
_beginthread_trampoline_t local_trampoline;
thread_data_t *data = msvcrt_get_thread_data();
memcpy(&local_trampoline, arg, sizeof(local_trampoline));
data->handle = local_trampoline.thread;
free(arg);
retval = local_trampoline.start_address_ex(local_trampoline.arglist);
_endthreadex(retval);
}
/*********************************************************************
* _beginthreadex (MSVCRT.@)
*/
uintptr_t CDECL _beginthreadex(
......@@ -158,12 +177,30 @@ uintptr_t CDECL _beginthreadex(
unsigned int initflag, /* [in] Initial state of new thread (0 for running or CREATE_SUSPEND for suspended) */
unsigned int *thrdaddr) /* [out] Points to a 32-bit variable that receives the thread identifier */
{
_beginthread_trampoline_t* trampoline;
HANDLE thread;
TRACE("(%p, %d, %p, %p, %d, %p)\n", security, stack_size, start_address, arglist, initflag, thrdaddr);
/* FIXME */
return (uintptr_t)CreateThread(security, stack_size,
start_address, arglist,
initflag, thrdaddr);
/* FIXME: may use different errno / return values */
if (!MSVCRT_CHECK_PMT(start_address)) return 0;
if (!(trampoline = malloc(sizeof(*trampoline))))
return 0;
trampoline->thread = INVALID_HANDLE_VALUE;
trampoline->start_address_ex = start_address;
trampoline->arglist = arglist;
thread = CreateThread(security, stack_size, _beginthreadex_trampoline,
trampoline, initflag, thrdaddr);
if(!thread) {
free(trampoline);
msvcrt_set_errno(GetLastError());
return 0;
}
return (uintptr_t)thread;
}
#if _MSVCR_VER>=80
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment