/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

/* This is a minimal pthread implementation based on windows functions.
 * It is *not* intended to be complete - just complete enough to get
 * BRLTTY running.
 */

#ifndef BRLTTY_INCLUDED_WIN_PTHREAD
#define BRLTTY_INCLUDED_WIN_PTHREAD

#include "prologue.h"

#include <windows.h>
#include <stdio.h>
#include <errno.h>
#include <sys/time.h>

#include "gettime.h"

#ifndef ETIMEDOUT
#define ETIMEDOUT EAGAIN
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#define winPthreadAssertWindows(expr) do { if (!(expr)) { setSystemErrno(); return errno; } } while (0)
#define winPthreadAssertPthread(expr) do { int ret = (expr); if (ret) return ret; } while (0)
#define winPthreadAssert(expr) do { if (!(expr)) return EIO; } while (0)

#if !defined(__struct_timespec_defined) && !defined(__MINGW64_VERSION_MAJOR)
struct timespec {
  time_t  tv_sec;  /* Seconds */
  long    tv_nsec; /* Nanoseconds */
};
#endif /* struct timespec */

static inline DWORD pthread_gettimeout_np(const struct timespec *abs_timeout) {
  struct timeval now;
  LONG timeout;
  getRealTime(&now);
  timeout = (abs_timeout->tv_sec  - now.tv_sec) * 1000 +
            (abs_timeout->tv_nsec - now.tv_usec * 1000) / 1000000;
  if (timeout < 0)
    timeout = 0;
  return timeout;
}

/***********
 * threads *
 ***********/

typedef DWORD pthread_attr_t;
typedef HANDLE pthread_t;

static inline pthread_t pthread_self(void) {
  return GetCurrentThread();
}

static inline int pthread_equal(pthread_t t1, pthread_t t2) {
  return t1 == t2;
}

static inline int pthread_attr_init (pthread_attr_t *attr) {
  *attr = 0;
  return 0;
}

#define PTHREAD_CREATE_DETACHED 1
static inline int pthread_attr_setdetachstate (pthread_attr_t *attr, int yes) {
  /* not supported, ignore */
  return 0;
}

static inline int pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize) {
  /* not supported, ignore */
  return 0;
}

static inline int pthread_attr_destroy (pthread_attr_t *attr) {
  return 0;
}

/* "real" cleanup handling not yet implemented */
typedef struct {
  void (*routine) (void *);
  void *arg;
} __pthread_cleanup_handler;

void pthread_cleanup_push (void (*routine) (void *), void *arg);
#define pthread_cleanup_push(routine, arg) do { \
  __pthread_cleanup_handler __cleanup_handler = {routine, arg};

void pthread_cleanup_pop (int execute);
#define pthread_cleanup_pop(execute) \
  if (execute) __cleanup_handler.routine(__cleanup_handler.arg); \
} while (0);

static inline int pthread_create (
  pthread_t *thread, const pthread_attr_t *attr,
  void * (*fun) (void *), void *arg
) {
  if (attr && *attr)
    return EINVAL;
  winPthreadAssertWindows(*thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) fun, arg, 0, NULL));
  return 0;
}

static inline int pthread_setcancelstate (int state, int *oldstate) {
  /* not yet implemented :( */
  return 0;
}

static inline int pthread_cancel (pthread_t thread) {
  /* This is quite harsh :( */
  winPthreadAssertWindows(TerminateThread(thread, 0));
  return 0;
}

static inline void pthread_exit (void *res) {
  ExitThread((DWORD) (DWORD_PTR) res);
}

static inline int pthread_join (pthread_t thread, void **res) {
again:
  switch (WaitForSingleObject(thread, INFINITE)) {
    default:
    case WAIT_FAILED:
      setSystemErrno();
      return errno;
    case WAIT_ABANDONED:
    case WAIT_OBJECT_0:
      break;
    case WAIT_TIMEOUT:
      goto again;
    }
  if (res) {
    DWORD _res;
    if (GetExitCodeThread(thread, &_res))
      *res = (void *)(DWORD_PTR)_res;
  }
  return 0;
}

/***********
 * mutexes *
 ***********/

#define PTHREAD_MUTEX_INITIALIZER NULL
typedef HANDLE pthread_mutex_t;
#define PTHREAD_MUTEX_RECURSIVE 1
typedef int pthread_mutexattr_t;

static inline int pthread_mutexattr_init(pthread_mutexattr_t *attr) {
  *attr = PTHREAD_MUTEX_RECURSIVE;
  return 0;
}

static inline int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) {
  if (type != PTHREAD_MUTEX_RECURSIVE)
    return EINVAL;
  *attr = type;
  return 0;
}

static inline int pthread_mutex_init (pthread_mutex_t *mutex, pthread_mutexattr_t *attr) {
  if (attr && *attr!=PTHREAD_MUTEX_RECURSIVE)
    return EINVAL;
  winPthreadAssertWindows(*mutex = CreateMutex(NULL, FALSE, NULL));
  return 0;
}

static inline int pthread_mutex_unlock (pthread_mutex_t *mutex) {
  winPthreadAssertWindows(ReleaseMutex(*mutex));
  return 0;
}

static inline int pthread_mutex_lock (pthread_mutex_t *mutex);
static inline int __pthread_mutex_alloc_concurrently (pthread_mutex_t *mutex) {
    HANDLE mutex_init_mutex;
  /* Get access to one global named mutex to serialize mutex initialization */
  winPthreadAssertWindows((mutex_init_mutex = CreateMutex(NULL, FALSE, "StarPU mutex init")));
  winPthreadAssertPthread(pthread_mutex_lock(&mutex_init_mutex));
  /* Now we are the one that can initialize it */
  if (!*mutex)
    winPthreadAssertPthread(pthread_mutex_init(mutex,NULL));
  winPthreadAssertPthread(pthread_mutex_unlock(&mutex_init_mutex));
    winPthreadAssertWindows(CloseHandle(mutex_init_mutex));
  return 0;
}

static inline int pthread_mutex_lock (pthread_mutex_t *mutex) {
  if (!*mutex)
    __pthread_mutex_alloc_concurrently (mutex);
again:
  switch (WaitForSingleObject(*mutex, INFINITE)) {
    default:
    case WAIT_FAILED:
      setSystemErrno();
      return errno;
    case WAIT_ABANDONED:
    case WAIT_OBJECT_0:
      return 0;
    case WAIT_TIMEOUT:
      goto again;
  }
}

static inline int pthread_mutex_trylock (pthread_mutex_t *mutex) {
  if (!*mutex)
    __pthread_mutex_alloc_concurrently (mutex);
  switch (WaitForSingleObject(*mutex, 0)) {
    default:
    case WAIT_FAILED:
      setSystemErrno();
      return errno;
    case WAIT_ABANDONED:
    case WAIT_OBJECT_0:
      return 0;
    case WAIT_TIMEOUT:
      return EBUSY;
  }
}

static inline int pthread_mutex_destroy (pthread_mutex_t *mutex) {
  winPthreadAssertWindows(CloseHandle(*mutex));
  *mutex = INVALID_HANDLE_VALUE;
  return 0;
}

/**************
 * semaphores *
 **************/

typedef HANDLE sem_t;

static inline int sem_init(sem_t *sem, int pshared, unsigned int value) {
  winPthreadAssertWindows(*sem = CreateSemaphore(NULL, value, MAXLONG, NULL));
  return 0;
}

static inline int do_sem_wait(sem_t *sem, DWORD timeout) {
  switch (WaitForSingleObject(*sem, timeout)) {
    default:
    case WAIT_FAILED:
      setSystemErrno();
      return -1;
    case WAIT_TIMEOUT:
      errno = EAGAIN;
      return -1;
    case WAIT_ABANDONED:
    case WAIT_OBJECT_0:
      return 0;
  }
}

#define sem_wait(sem) do_sem_wait(sem, INFINITE)
#define sem_trywait(sem) do_sem_wait(sem, 0)

static inline int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout) {
  return do_sem_wait(sem, pthread_gettimeout_np(abs_timeout));
}

static inline int sem_post(sem_t *sem) {
  winPthreadAssertWindows(ReleaseSemaphore(*sem, 1, NULL));
  return 0;
}

static inline int sem_destroy(sem_t *sem) {
  winPthreadAssertWindows(CloseHandle(*sem));
  return 0;
}

/**************
 * conditions *
 **************/

typedef struct {
  HANDLE sem;
  volatile unsigned nbwait;
} pthread_cond_t;
#define PTHREAD_COND_INITIALIZER { NULL, 0}

typedef unsigned pthread_condattr_t;

static inline int pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr) {
  if (attr)
    return EINVAL;
  winPthreadAssertWindows(cond->sem = CreateSemaphore(NULL, 0, MAXLONG, NULL));
  cond->nbwait = 0;
  return 0;
}

static inline int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *time) {
  if (!cond->sem)
    winPthreadAssertPthread(pthread_cond_init(cond,NULL));
  cond->nbwait++;
  winPthreadAssertPthread(pthread_mutex_unlock(mutex));
  switch (WaitForSingleObject(cond->sem, pthread_gettimeout_np(time))) {
    default:
    case WAIT_FAILED:
      setSystemErrno();
      winPthreadAssertPthread(pthread_mutex_lock(mutex));
      return errno;
    case WAIT_TIMEOUT:
      winPthreadAssertPthread(pthread_mutex_lock(mutex));
      return ETIMEDOUT;
    case WAIT_ABANDONED:
    case WAIT_OBJECT_0:
      break;
  }
  winPthreadAssertPthread(pthread_mutex_lock(mutex));
  cond->nbwait--;
  return 0;
}

static inline int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) {
  if (!cond->sem)
    winPthreadAssertPthread(pthread_cond_init(cond,NULL));
  cond->nbwait++;
  winPthreadAssertPthread(pthread_mutex_unlock(mutex));
again:
  switch (WaitForSingleObject(cond->sem, INFINITE)) {
    case WAIT_FAILED:
      setSystemErrno();
      winPthreadAssert(!pthread_mutex_lock(mutex));
      return errno;
    case WAIT_TIMEOUT:
      goto again;
    case WAIT_ABANDONED:
    case WAIT_OBJECT_0:
      break;
  }
  winPthreadAssertPthread(pthread_mutex_lock(mutex));
  cond->nbwait--;
  return 0;
}

static inline int pthread_cond_signal (pthread_cond_t *cond) {
  if (!cond->sem)
    winPthreadAssertPthread(pthread_cond_init(cond,NULL));
  if (cond->nbwait)
    ReleaseSemaphore(cond->sem, 1, NULL);
  return 0;
}

static inline int pthread_cond_broadcast (pthread_cond_t *cond) {
  if (!cond->sem)
    winPthreadAssertPthread(pthread_cond_init(cond,NULL));
  ReleaseSemaphore(cond->sem, cond->nbwait, NULL);
  return 0;
}

static inline int pthread_cond_destroy (pthread_cond_t *cond) {
  if (cond->sem) {
  winPthreadAssertWindows(CloseHandle(cond->sem));
    cond->sem = NULL;
  }
  return 0;
}

/*******
 * TLS *
 *******/

typedef DWORD pthread_key_t;
#define PTHREAD_ONCE_INIT {PTHREAD_MUTEX_INITIALIZER, 0}
typedef struct {
  pthread_mutex_t mutex;
  unsigned done;
} pthread_once_t;

static inline int pthread_once (pthread_once_t *once, void (*oncefun)(void)) {
  winPthreadAssertPthread(pthread_mutex_lock(&once->mutex));
  if (!once->done) {
    oncefun();
    once->done = 1;
  }
  winPthreadAssertPthread(pthread_mutex_unlock(&once->mutex));
  return 0;
}

static inline int pthread_key_create (pthread_key_t *key, void (*freefun)(void *)) {
  DWORD res;
  winPthreadAssertWindows((res = TlsAlloc()) != 0xFFFFFFFF);
  *key = res;
  return 0;
}

static inline int pthread_key_delete (pthread_key_t key) {
  winPthreadAssertWindows(TlsFree(key));
  return 0;
}

static inline void *pthread_getspecific (pthread_key_t key) {
  return TlsGetValue(key);
}

static inline int pthread_setspecific (pthread_key_t key, const void *data) {
  winPthreadAssertWindows(TlsSetValue(key, (LPVOID) data));
  return 0;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* BRLTTY_INCLUDED_WIN_PTHREAD */
