]> git.proxmox.com Git - libgit2.git/blame - src/win32/pthread.c
Merge pull request #987 from pwkelley/pthread_cond
[libgit2.git] / src / win32 / pthread.c
CommitLineData
bbcc7ffc 1/*
5e0de328 2 * Copyright (C) 2009-2012 the libgit2 contributors
bbcc7ffc 3 *
bb742ede
VM
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
bbcc7ffc
VM
6 */
7
8#include "pthread.h"
9
deafee7b
RB
10int pthread_create(
11 pthread_t *GIT_RESTRICT thread,
12 const pthread_attr_t *GIT_RESTRICT attr,
13 void *(*start_routine)(void*),
14 void *GIT_RESTRICT arg)
bbcc7ffc 15{
854eccbb 16 GIT_UNUSED(attr);
deafee7b
RB
17 *thread = (pthread_t) CreateThread(
18 NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, NULL);
19 return *thread ? 0 : -1;
bbcc7ffc
VM
20}
21
bbcc7ffc
VM
22int pthread_join(pthread_t thread, void **value_ptr)
23{
87d9869f
VM
24 int ret;
25 ret = WaitForSingleObject(thread, INFINITE);
26 if (ret && value_ptr)
27 GetExitCodeThread(thread, (void*) value_ptr);
28 return -(!!ret);
bbcc7ffc
VM
29}
30
bb3de0c4 31int pthread_mutex_init(pthread_mutex_t *GIT_RESTRICT mutex,
854eccbb 32 const pthread_mutexattr_t *GIT_RESTRICT mutexattr)
bbcc7ffc 33{
854eccbb 34 GIT_UNUSED(mutexattr);
87d9869f
VM
35 InitializeCriticalSection(mutex);
36 return 0;
bbcc7ffc
VM
37}
38
39int pthread_mutex_destroy(pthread_mutex_t *mutex)
40{
87d9869f
VM
41 DeleteCriticalSection(mutex);
42 return 0;
bbcc7ffc
VM
43}
44
bb3de0c4 45int pthread_mutex_lock(pthread_mutex_t *mutex)
bbcc7ffc 46{
87d9869f
VM
47 EnterCriticalSection(mutex);
48 return 0;
bbcc7ffc
VM
49}
50
bb3de0c4 51int pthread_mutex_unlock(pthread_mutex_t *mutex)
bbcc7ffc 52{
87d9869f
VM
53 LeaveCriticalSection(mutex);
54 return 0;
bbcc7ffc
VM
55}
56
5e4f2b5f
PK
57int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
58{
59 /* We don't support non-default attributes. */
60 if (attr)
61 return EINVAL;
62
63 /* This is an auto-reset event. */
64 *cond = CreateEventW(NULL, FALSE, FALSE, NULL);
65 assert(*cond);
66
67 /* If we can't create the event, claim that the reason was out-of-memory.
68 * The actual reason can be fetched with GetLastError(). */
69 return *cond ? 0 : ENOMEM;
70}
71
72int pthread_cond_destroy(pthread_cond_t *cond)
73{
74 BOOL closed;
75
76 if (!cond)
77 return EINVAL;
78
79 closed = CloseHandle(*cond);
80 assert(closed);
81
82 *cond = NULL;
83 return 0;
84}
85
86int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
87{
88 int error;
89 DWORD wait_result;
90
91 if (!cond || !mutex)
92 return EINVAL;
93
94 /* The caller must be holding the mutex. */
95 error = pthread_mutex_unlock(mutex);
96
97 if (error)
98 return error;
99
100 wait_result = WaitForSingleObject(*cond, INFINITE);
101 assert(WAIT_OBJECT_0 == wait_result);
102
103 return pthread_mutex_lock(mutex);
104}
105
106int pthread_cond_signal(pthread_cond_t *cond)
107{
108 BOOL signaled;
109
110 if (!cond)
111 return EINVAL;
112
113 signaled = SetEvent(*cond);
114 assert(signaled);
115
116 return 0;
117}
118
119/* pthread_cond_broadcast is not implemented because doing so with just Win32 events
120 * is quite complicated, and no caller in libgit2 uses it yet. */
121
bbcc7ffc
VM
122int pthread_num_processors_np(void)
123{
87d9869f
VM
124 DWORD_PTR p, s;
125 int n = 0;
bbcc7ffc 126
87d9869f
VM
127 if (GetProcessAffinityMask(GetCurrentProcess(), &p, &s))
128 for (; p; p >>= 1)
129 n += p&1;
bbcc7ffc 130
87d9869f 131 return n ? n : 1;
bbcc7ffc
VM
132}
133