1 /* 2 * msvcrt.dll thread functions 3 * 4 * Copyright 2000 Jon Griffiths 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <precomp.h> 22 #include <malloc.h> 23 #include <process.h> 24 25 typedef void (*_beginthread_start_routine_t)(void *); 26 typedef unsigned int (__stdcall *_beginthreadex_start_routine_t)(void *); 27 28 /********************************************************************/ 29 30 typedef struct { 31 HANDLE thread; 32 _beginthread_start_routine_t start_address; 33 void *arglist; 34 } _beginthread_trampoline_t; 35 36 /********************************************************************* 37 * _beginthread_trampoline 38 */ 39 static DWORD CALLBACK _beginthread_trampoline(LPVOID arg) 40 { 41 _beginthread_trampoline_t local_trampoline; 42 thread_data_t *data = msvcrt_get_thread_data(); 43 44 memcpy(&local_trampoline,arg,sizeof(local_trampoline)); 45 data->handle = local_trampoline.thread; 46 free(arg); 47 48 local_trampoline.start_address(local_trampoline.arglist); 49 return 0; 50 } 51 52 /********************************************************************* 53 * _beginthread (MSVCRT.@) 54 */ 55 uintptr_t _beginthread( 56 _beginthread_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */ 57 unsigned int stack_size, /* [in] Stack size for new thread or 0 */ 58 void *arglist) /* [in] Argument list to be passed to new thread or NULL */ 59 { 60 _beginthread_trampoline_t* trampoline; 61 HANDLE thread; 62 63 TRACE("(%p, %d, %p)\n", start_address, stack_size, arglist); 64 65 trampoline = malloc(sizeof(*trampoline)); 66 if(!trampoline) { 67 *_errno() = EAGAIN; 68 return -1; 69 } 70 71 thread = CreateThread(NULL, stack_size, _beginthread_trampoline, 72 trampoline, CREATE_SUSPENDED, NULL); 73 if(!thread) { 74 free(trampoline); 75 *_errno() = EAGAIN; 76 return -1; 77 } 78 79 trampoline->thread = thread; 80 trampoline->start_address = start_address; 81 trampoline->arglist = arglist; 82 83 if(ResumeThread(thread) == -1) { 84 free(trampoline); 85 *_errno() = EAGAIN; 86 return -1; 87 } 88 89 return (uintptr_t)thread; 90 } 91 92 /********************************************************************* 93 * _endthread (MSVCRT.@) 94 */ 95 void CDECL _endthread(void) 96 { 97 TRACE("(void)\n"); 98 99 /* FIXME */ 100 ExitThread(0); 101 } 102