77 lines
1.7 KiB
C
77 lines
1.7 KiB
C
#ifndef JV_THREAD_H
|
|
#define JV_THREAD_H
|
|
|
|
#ifdef WIN32
|
|
#ifndef __MINGW32__
|
|
#include <windows.h>
|
|
#include <winnt.h>
|
|
#include <errno.h>
|
|
|
|
/* Copied from Heimdal: pthread-like mutexes for WIN32 -- see lib/base/heimbase.h in Heimdal */
|
|
typedef struct pthread_mutex {
|
|
HANDLE h;
|
|
} pthread_mutex_t;
|
|
|
|
#define PTHREAD_MUTEX_INITIALIZER { INVALID_HANDLE_VALUE }
|
|
|
|
static inline int
|
|
pthread_mutex_init(pthread_mutex_t *m)
|
|
{
|
|
m->h = CreateSemaphore(NULL, 1, 1, NULL);
|
|
if (m->h == INVALID_HANDLE_VALUE)
|
|
return EAGAIN;
|
|
return 0;
|
|
}
|
|
|
|
static inline int
|
|
pthread_mutex_lock(pthread_mutex_t *m)
|
|
{
|
|
HANDLE h, new_h;
|
|
int created = 0;
|
|
|
|
h = InterlockedCompareExchangePointer(&m->h, m->h, m->h);
|
|
if (h == INVALID_HANDLE_VALUE || h == NULL) {
|
|
created = 1;
|
|
new_h = CreateSemaphore(NULL, 0, 1, NULL);
|
|
if (new_h == INVALID_HANDLE_VALUE)
|
|
return EAGAIN;
|
|
if (InterlockedCompareExchangePointer(&m->h, new_h, h) != h) {
|
|
created = 0;
|
|
CloseHandle(new_h);
|
|
}
|
|
}
|
|
if (!created)
|
|
WaitForSingleObject(m->h, INFINITE);
|
|
return 0;
|
|
}
|
|
|
|
static inline int
|
|
pthread_mutex_unlock(pthread_mutex_t *m)
|
|
{
|
|
if (ReleaseSemaphore(m->h, 1, NULL) == FALSE)
|
|
return EPERM;
|
|
return 0;
|
|
}
|
|
static inline int
|
|
pthread_mutex_destroy(pthread_mutex_t *m)
|
|
{
|
|
HANDLE h;
|
|
|
|
h = InterlockedCompareExchangePointer(&m->h, INVALID_HANDLE_VALUE, m->h);
|
|
if (h != INVALID_HANDLE_VALUE)
|
|
CloseHandle(h);
|
|
return 0;
|
|
}
|
|
|
|
typedef unsigned long pthread_key_t;
|
|
int pthread_key_create(pthread_key_t *, void (*)(void *));
|
|
int pthread_setspecific(pthread_key_t, void *);
|
|
void *pthread_getspecific(pthread_key_t);
|
|
#else
|
|
#include <pthread.h>
|
|
#endif
|
|
#else
|
|
#include <pthread.h>
|
|
#endif
|
|
#endif /* JV_THREAD_H */
|