xref: /reactos/sdk/lib/crt/process/thread.c (revision 50cf16b3)
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