remove wine's broken _beginthread() and _endthread() and implement them properly
[reactos.git] / reactos / lib / crt / process / thread.c
1 #include <precomp.h>
2
3 void _endthread(void);
4
5 static DWORD WINAPI
6 _beginthread_start(PVOID lpParameter)
7 {
8 PTHREADDATA ThreadData = (PTHREADDATA)lpParameter;
9
10 if (SetThreadData(ThreadData))
11 {
12 /* FIXME - wrap start_address in SEH! */
13 ThreadData->start_address(ThreadData->arglist);
14
15 _endthread();
16 }
17 else
18 {
19 /* couldn't set the thread data, free it before terminating */
20 free(ThreadData);
21 }
22
23 ExitThread(0);
24 }
25
26
27 /*
28 * @implemented
29 *
30 * FIXME: the return type should be uintptr_t
31 */
32 unsigned long _beginthread(
33 void (__cdecl *start_address)(void*),
34 unsigned stack_size,
35 void* arglist)
36 {
37 HANDLE hThread;
38 PTHREADDATA ThreadData;
39
40 if (start_address == NULL) {
41 __set_errno(EINVAL);
42 return (unsigned long)-1;
43 }
44
45 /* allocate the thread data structure already here instead of allocating the
46 thread data structure in the thread itself. this way we can pass an error
47 code to the caller in case we don't have sufficient resources */
48 ThreadData = malloc(sizeof(THREADDATA));
49 if (ThreadData == NULL)
50 {
51 __set_errno(EAGAIN);
52 return (unsigned long)-1;
53 }
54
55 ThreadData->start_address = start_address;
56 ThreadData->arglist = arglist;
57
58 hThread = CreateThread(NULL,
59 stack_size,
60 _beginthread_start,
61 ThreadData,
62 CREATE_SUSPENDED,
63 NULL);
64 if (hThread == NULL)
65 {
66 free(ThreadData);
67 __set_errno(EAGAIN);
68 return (unsigned long)-1;
69 }
70
71 ThreadData->hThread = hThread;
72
73 if (ResumeThread(hThread) == (DWORD)-1)
74 {
75 CloseHandle(hThread);
76
77 /* freeing the ThreadData _could_ cause a crash, but only in case someone
78 else resumed the thread and it got to free the context before we actually
79 get here, but that's _very_ unlikely! */
80 free(ThreadData);
81 __set_errno(EAGAIN);
82 return (unsigned long)-1;
83 }
84
85 return (unsigned long)hThread;
86 }
87
88 /*
89 * @implemented
90 */
91 void _endthread(void)
92 {
93 PTHREADDATA ThreadData = GetThreadData();
94
95 /* close the thread handle */
96 CloseHandle(ThreadData->hThread);
97
98 /* NOTE: the thread data will be freed in the thread detach routine that will
99 call FreeThreadData */
100
101 ExitThread(0);
102 }