summaryrefslogtreecommitdiff
path: root/sync.c
blob: 20009acd9ef6e7994cf73759a8ce669fee0fad30 (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
/*
 * 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;
  _pthread_threads_thread_t * target;

  pthread_t us = pthread_self();

  /* First check if we are trying to join to ourselves. */
  if (pthread_equal(thread, us) == 0)
    {
      return EDEADLK;
    }

  /* If the thread is detached, then join will return immediately. */

  target = _pthread_find_thread_entry(thread);
  if (target < 0)
    {
      return EINVAL;
    }
  else if (target->detached == PTHREAD_CREATE_DETACHED)
    {
      return ESRCH;
    }

  /* 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;
}