mirror of
https://github.com/git-for-windows/git.git
synced 2026-02-04 03:33:01 -06:00
When asking the mingw-w64 variant of GCC to compile C11 code, it seems to link implicitly to libwinpthread, which does implement a pthread emulation (that is more complete than Git's). In preparation for vendoring in mimalloc (which requires C11 support), let's keep preferring Git's own pthread emulation. To avoid linker errors where it thinks that the `pthread_self` and the `pthread_create` symbols are defined twice, let's give our version a `win32_` prefix, just like we already do for `pthread_join()`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
69 lines
1.6 KiB
C
69 lines
1.6 KiB
C
/*
|
|
* Copyright (C) 2009 Andrzej K. Haczewski <ahaczewski@gmail.com>
|
|
*
|
|
* DISCLAIMER: The implementation is Git-specific, it is subset of original
|
|
* Pthreads API, without lots of other features that Git doesn't use.
|
|
* Git also makes sure that the passed arguments are valid, so there's
|
|
* no need for double-checking.
|
|
*/
|
|
|
|
#include "../../git-compat-util.h"
|
|
#include "pthread.h"
|
|
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
|
|
static unsigned __stdcall win32_start_routine(void *arg)
|
|
{
|
|
pthread_t *thread = arg;
|
|
thread->tid = GetCurrentThreadId();
|
|
thread->arg = thread->start_routine(thread->arg);
|
|
return 0;
|
|
}
|
|
|
|
int win32_pthread_create(pthread_t *thread, const void *attr UNUSED,
|
|
void *(*start_routine)(void *), void *arg)
|
|
{
|
|
thread->arg = arg;
|
|
thread->start_routine = start_routine;
|
|
thread->handle = (HANDLE)_beginthreadex(NULL, 0, win32_start_routine,
|
|
thread, 0, NULL);
|
|
|
|
if (!thread->handle)
|
|
return errno;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
int win32_pthread_join(pthread_t *thread, void **value_ptr)
|
|
{
|
|
DWORD result = WaitForSingleObject(thread->handle, INFINITE);
|
|
switch (result) {
|
|
case WAIT_OBJECT_0:
|
|
if (value_ptr)
|
|
*value_ptr = thread->arg;
|
|
CloseHandle(thread->handle);
|
|
return 0;
|
|
case WAIT_ABANDONED:
|
|
CloseHandle(thread->handle);
|
|
return EINVAL;
|
|
default:
|
|
/* the wait failed, so do not detach */
|
|
return err_win_to_posix(GetLastError());
|
|
}
|
|
}
|
|
|
|
pthread_t win32_pthread_self(void)
|
|
{
|
|
pthread_t t = { NULL };
|
|
t.tid = GetCurrentThreadId();
|
|
return t;
|
|
}
|
|
|
|
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
|
{
|
|
if (SleepConditionVariableCS(cond, mutex, INFINITE) == 0)
|
|
return err_win_to_posix(GetLastError());
|
|
return 0;
|
|
}
|