git/compat/win32/pthread.c
Johannes Schindelin 18d8514591 win32/pthread: avoid name clashes with winpthread
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>
2026-02-02 18:10:10 +01:00

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