/* Timed mutexes (native Windows implementation).
   Copyright (C) 2005-2020 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <https://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>, 2005, 2019.
   Based on GCC's gthr-win32.h.  */

#include <config.h>

/* Specification.  */
#include "windows-timedmutex.h"

#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>

int
glwthread_timedmutex_init (glwthread_timedmutex_t *mutex)
{
  /* Attempt to allocate an auto-reset event object.  */
  /* CreateEvent
     <https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-createeventa> */
  HANDLE event = CreateEvent (NULL, FALSE, FALSE, NULL);
  if (event == INVALID_HANDLE_VALUE)
    return EAGAIN;
  mutex->event = event;
  InitializeCriticalSection (&mutex->lock);
  mutex->guard.done = 1;
  return 0;
}

int
glwthread_timedmutex_lock (glwthread_timedmutex_t *mutex)
{
  if (!mutex->guard.done)
    {
      if (InterlockedIncrement (&mutex->guard.started) == 0)
        {
          /* This thread is the first one to need this mutex.
             Initialize it.  */
          int err = glwthread_timedmutex_init (mutex);
          if (err != 0)
            {
              /* Undo increment.  */
              InterlockedDecrement (&mutex->guard.started);
              return err;
            }
        }
      else
        {
          /* Don't let mutex->guard.started grow and wrap around.  */
          InterlockedDecrement (&mutex->guard.started);
          /* Yield the CPU while waiting for another thread to finish
             initializing this mutex.  */
          while (!mutex->guard.done)
            Sleep (0);
        }
    }
  EnterCriticalSection (&mutex->lock);
  return 0;
}

int
glwthread_timedmutex_trylock (glwthread_timedmutex_t *mutex)
{
  if (!mutex->guard.done)
    {
      if (InterlockedIncrement (&mutex->guard.started) == 0)
        {
          /* This thread is the first one to need this mutex.
             Initialize it.  */
          int err = glwthread_timedmutex_init (mutex);
          if (err != 0)
            {
              /* Undo increment.  */
              InterlockedDecrement (&mutex->guard.started);
              return err;
            }
        }
      else
        {
          /* Don't let mutex->guard.started grow and wrap around.  */
          InterlockedDecrement (&mutex->guard.started);
          /* Let another thread finish initializing this mutex, and let it also
             lock this mutex.  */
          return EBUSY;
        }
    }
  if (!TryEnterCriticalSection (&mutex->lock))
    return EBUSY;
  return 0;
}

int
glwthread_timedmutex_timedlock (glwthread_timedmutex_t *mutex,
                                const struct timespec *abstime)
{
  if (!mutex->guard.done)
    {
      if (InterlockedIncrement (&mutex->guard.started) == 0)
        {
          /* This thread is the first one to need this mutex.
             Initialize it.  */
          int err = glwthread_timedmutex_init (mutex);
          if (err != 0)
            {
              /* Undo increment.  */
              InterlockedDecrement (&mutex->guard.started);
              return err;
            }
        }
      else
        {
          /* Don't let mutex->guard.started grow and wrap around.  */
          InterlockedDecrement (&mutex->guard.started);
          /* Yield the CPU while waiting for another thread to finish
             initializing this mutex.  */
          while (!mutex->guard.done)
            Sleep (0);
        }
    }

  /* POSIX says:
      "Under no circumstance shall the function fail with a timeout if
       the mutex can be locked immediately. The validity of the abstime
       parameter need not be checked if the mutex can be locked
       immediately."
     Therefore start the loop with a TryEnterCriticalSection call.  */
  for (;;)
    {
      if (TryEnterCriticalSection (&mutex->lock))
        break;

      {
        struct timeval currtime;
        DWORD timeout;
        DWORD result;

        gettimeofday (&currtime, NULL);

        /* Wait until another thread signals the event or until the
           abstime passes.  */
        if (currtime.tv_sec > abstime->tv_sec)
          timeout = 0;
        else
          {
            unsigned long seconds = abstime->tv_sec - currtime.tv_sec;
            timeout = seconds * 1000;
            if (timeout / 1000 != seconds) /* overflow? */
              timeout = INFINITE;
            else
              {
                long milliseconds =
                  abstime->tv_nsec / 1000000 - currtime.tv_usec / 1000;
                if (milliseconds >= 0)
                  {
                    timeout += milliseconds;
                    if (timeout < milliseconds) /* overflow? */
                      timeout = INFINITE;
                  }
                else
                  {
                    if (timeout >= - milliseconds)
                      timeout -= (- milliseconds);
                    else
                      timeout = 0;
                  }
              }
          }
        if (timeout == 0)
          return ETIMEDOUT;

        /* WaitForSingleObject
           <https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject> */
        result = WaitForSingleObject (mutex->event, timeout);
        if (result == WAIT_FAILED)
          abort ();
        if (result == WAIT_TIMEOUT)
          return ETIMEDOUT;
        /* Another thread has just unlocked the mutex.  We have good chances at
           locking it now.  */
      }
    }
  return 0;
}

int
glwthread_timedmutex_unlock (glwthread_timedmutex_t *mutex)
{
  if (!mutex->guard.done)
    return EINVAL;
  LeaveCriticalSection (&mutex->lock);
  /* Notify one of the threads that were waiting with a timeout.  */
  /* SetEvent
     <https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-setevent> */
  SetEvent (mutex->event);
  return 0;
}

int
glwthread_timedmutex_destroy (glwthread_timedmutex_t *mutex)
{
  if (!mutex->guard.done)
    return EINVAL;
  DeleteCriticalSection (&mutex->lock);
  /* CloseHandle
     <https://docs.microsoft.com/en-us/windows/desktop/api/handleapi/nf-handleapi-closehandle> */
  CloseHandle (mutex->event);
  mutex->guard.done = 0;
  return 0;
}
