Blame gl/tests/windows-mutex.c

Packit Service 991b93
/* Plain mutexes (native Windows implementation).
Packit Service 991b93
   Copyright (C) 2005-2020 Free Software Foundation, Inc.
Packit Service 991b93
Packit Service 991b93
   This program is free software; you can redistribute it and/or modify
Packit Service 991b93
   it under the terms of the GNU General Public License as published by
Packit Service 991b93
   the Free Software Foundation; either version 3, or (at your option)
Packit Service 991b93
   any later version.
Packit Service 991b93
Packit Service 991b93
   This program is distributed in the hope that it will be useful,
Packit Service 991b93
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 991b93
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 991b93
   GNU General Public License for more details.
Packit Service 991b93
Packit Service 991b93
   You should have received a copy of the GNU General Public License
Packit Service 991b93
   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
Packit Service 991b93
Packit Service 991b93
/* Written by Bruno Haible <bruno@clisp.org>, 2005.
Packit Service 991b93
   Based on GCC's gthr-win32.h.  */
Packit Service 991b93
Packit Service 991b93
#include <config.h>
Packit Service 991b93
Packit Service 991b93
/* Specification.  */
Packit Service 991b93
#include "windows-mutex.h"
Packit Service 991b93
Packit Service 991b93
#include <errno.h>
Packit Service 991b93
Packit Service 991b93
void
Packit Service 991b93
glwthread_mutex_init (glwthread_mutex_t *mutex)
Packit Service 991b93
{
Packit Service 991b93
  InitializeCriticalSection (&mutex->lock);
Packit Service 991b93
  mutex->guard.done = 1;
Packit Service 991b93
}
Packit Service 991b93
Packit Service 991b93
int
Packit Service 991b93
glwthread_mutex_lock (glwthread_mutex_t *mutex)
Packit Service 991b93
{
Packit Service 991b93
  if (!mutex->guard.done)
Packit Service 991b93
    {
Packit Service 991b93
      if (InterlockedIncrement (&mutex->guard.started) == 0)
Packit Service 991b93
        /* This thread is the first one to need this mutex.  Initialize it.  */
Packit Service 991b93
        glwthread_mutex_init (mutex);
Packit Service 991b93
      else
Packit Service 991b93
        {
Packit Service 991b93
          /* Don't let mutex->guard.started grow and wrap around.  */
Packit Service 991b93
          InterlockedDecrement (&mutex->guard.started);
Packit Service 991b93
          /* Yield the CPU while waiting for another thread to finish
Packit Service 991b93
             initializing this mutex.  */
Packit Service 991b93
          while (!mutex->guard.done)
Packit Service 991b93
            Sleep (0);
Packit Service 991b93
        }
Packit Service 991b93
    }
Packit Service 991b93
  EnterCriticalSection (&mutex->lock);
Packit Service 991b93
  return 0;
Packit Service 991b93
}
Packit Service 991b93
Packit Service 991b93
int
Packit Service 991b93
glwthread_mutex_trylock (glwthread_mutex_t *mutex)
Packit Service 991b93
{
Packit Service 991b93
  if (!mutex->guard.done)
Packit Service 991b93
    {
Packit Service 991b93
      if (InterlockedIncrement (&mutex->guard.started) == 0)
Packit Service 991b93
        /* This thread is the first one to need this mutex.  Initialize it.  */
Packit Service 991b93
        glwthread_mutex_init (mutex);
Packit Service 991b93
      else
Packit Service 991b93
        {
Packit Service 991b93
          /* Don't let mutex->guard.started grow and wrap around.  */
Packit Service 991b93
          InterlockedDecrement (&mutex->guard.started);
Packit Service 991b93
          /* Let another thread finish initializing this mutex, and let it also
Packit Service 991b93
             lock this mutex.  */
Packit Service 991b93
          return EBUSY;
Packit Service 991b93
        }
Packit Service 991b93
    }
Packit Service 991b93
  if (!TryEnterCriticalSection (&mutex->lock))
Packit Service 991b93
    return EBUSY;
Packit Service 991b93
  return 0;
Packit Service 991b93
}
Packit Service 991b93
Packit Service 991b93
int
Packit Service 991b93
glwthread_mutex_unlock (glwthread_mutex_t *mutex)
Packit Service 991b93
{
Packit Service 991b93
  if (!mutex->guard.done)
Packit Service 991b93
    return EINVAL;
Packit Service 991b93
  LeaveCriticalSection (&mutex->lock);
Packit Service 991b93
  return 0;
Packit Service 991b93
}
Packit Service 991b93
Packit Service 991b93
int
Packit Service 991b93
glwthread_mutex_destroy (glwthread_mutex_t *mutex)
Packit Service 991b93
{
Packit Service 991b93
  if (!mutex->guard.done)
Packit Service 991b93
    return EINVAL;
Packit Service 991b93
  DeleteCriticalSection (&mutex->lock);
Packit Service 991b93
  mutex->guard.done = 0;
Packit Service 991b93
  return 0;
Packit Service 991b93
}