blob: c4e43274f26dc78371580e734241b2f860f49027 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
/*
* sync.c
*
* Description:
* This translation unit implements functions related to thread
* synchronisation.
*/
#include "pthread.h"
int
pthread_join(pthread_t thread, void ** valueptr)
{
LPDWORD exitcode;
int detachstate;
pthread_t us = pthread_self();
/* First check if we are trying to join to ourselves. */
if (pthread_equal(thread, us) == 0)
{
return EDEADLK;
}
/* Find the thread. */
this = _pthread_find_thread_entry(thread);
if (this == -1)
{
return ESRCH;
}
/* If the thread is detached, then join will return immediately. */
if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0
|| detachstate == PTHREAD_CREATE_DETACHED)
{
return EINVAL;
}
this->joinvalueptr = valueptr;
/* Wait on the kernel thread object. */
switch (WaitForSingleObject(thread, INFINITE))
{
case WAIT_FAILED:
/* The thread does not exist. */
return ESRCH;
case WAIT_OBJECT_0:
/* The thread has finished. */
break;
default:
/* This should never happen. */
break;
}
/* We don't get the exit code as a result of the last operation,
so we do it now. */
if (GetExitCodeThread(thread, exitcode) != TRUE)
{
return ESRCH;
}
/* FIXME: this is wrong. */
return &exitcode;
}
int
pthread_detach(pthread_t thread)
{
_pthread_threads_thread_t * this;
int detachstate;
this = _pthread_find_thread_entry(thread);
if (this == -1)
{
return ESRCH;
}
/* Check that we can detach this thread. */
if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0
|| detachstate == PTHREAD_CREATE_DETACHED)
{
return EINVAL;
}
this->attr.detached = PTHREAD_CREATE_DETACHED;
if (CloseHandle(thread) != TRUE)
{
return ESRCH;
}
return 0;
}
|