1*820c1a8dSHiroo HAYASHI /* Plain mutexes (native Windows implementation). 2*820c1a8dSHiroo HAYASHI Copyright (C) 2005-2021 Free Software Foundation, Inc. 3*820c1a8dSHiroo HAYASHI 4*820c1a8dSHiroo HAYASHI This file is free software: you can redistribute it and/or modify 5*820c1a8dSHiroo HAYASHI it under the terms of the GNU Lesser General Public License as 6*820c1a8dSHiroo HAYASHI published by the Free Software Foundation; either version 2.1 of the 7*820c1a8dSHiroo HAYASHI License, or (at your option) any later version. 8*820c1a8dSHiroo HAYASHI 9*820c1a8dSHiroo HAYASHI This file is distributed in the hope that it will be useful, 10*820c1a8dSHiroo HAYASHI but WITHOUT ANY WARRANTY; without even the implied warranty of 11*820c1a8dSHiroo HAYASHI MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*820c1a8dSHiroo HAYASHI GNU Lesser General Public License for more details. 13*820c1a8dSHiroo HAYASHI 14*820c1a8dSHiroo HAYASHI You should have received a copy of the GNU Lesser General Public License 15*820c1a8dSHiroo HAYASHI along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16*820c1a8dSHiroo HAYASHI 17*820c1a8dSHiroo HAYASHI /* Written by Bruno Haible <bruno@clisp.org>, 2005. 18*820c1a8dSHiroo HAYASHI Based on GCC's gthr-win32.h. */ 19*820c1a8dSHiroo HAYASHI 20*820c1a8dSHiroo HAYASHI #include <config.h> 21*820c1a8dSHiroo HAYASHI 22*820c1a8dSHiroo HAYASHI /* Specification. */ 23*820c1a8dSHiroo HAYASHI #include "windows-mutex.h" 24*820c1a8dSHiroo HAYASHI 25*820c1a8dSHiroo HAYASHI #include <errno.h> 26*820c1a8dSHiroo HAYASHI 27*820c1a8dSHiroo HAYASHI void glwthread_mutex_init(glwthread_mutex_t * mutex)28*820c1a8dSHiroo HAYASHIglwthread_mutex_init (glwthread_mutex_t *mutex) 29*820c1a8dSHiroo HAYASHI { 30*820c1a8dSHiroo HAYASHI InitializeCriticalSection (&mutex->lock); 31*820c1a8dSHiroo HAYASHI mutex->guard.done = 1; 32*820c1a8dSHiroo HAYASHI } 33*820c1a8dSHiroo HAYASHI 34*820c1a8dSHiroo HAYASHI int glwthread_mutex_lock(glwthread_mutex_t * mutex)35*820c1a8dSHiroo HAYASHIglwthread_mutex_lock (glwthread_mutex_t *mutex) 36*820c1a8dSHiroo HAYASHI { 37*820c1a8dSHiroo HAYASHI if (!mutex->guard.done) 38*820c1a8dSHiroo HAYASHI { 39*820c1a8dSHiroo HAYASHI if (InterlockedIncrement (&mutex->guard.started) == 0) 40*820c1a8dSHiroo HAYASHI /* This thread is the first one to need this mutex. Initialize it. */ 41*820c1a8dSHiroo HAYASHI glwthread_mutex_init (mutex); 42*820c1a8dSHiroo HAYASHI else 43*820c1a8dSHiroo HAYASHI { 44*820c1a8dSHiroo HAYASHI /* Don't let mutex->guard.started grow and wrap around. */ 45*820c1a8dSHiroo HAYASHI InterlockedDecrement (&mutex->guard.started); 46*820c1a8dSHiroo HAYASHI /* Yield the CPU while waiting for another thread to finish 47*820c1a8dSHiroo HAYASHI initializing this mutex. */ 48*820c1a8dSHiroo HAYASHI while (!mutex->guard.done) 49*820c1a8dSHiroo HAYASHI Sleep (0); 50*820c1a8dSHiroo HAYASHI } 51*820c1a8dSHiroo HAYASHI } 52*820c1a8dSHiroo HAYASHI EnterCriticalSection (&mutex->lock); 53*820c1a8dSHiroo HAYASHI return 0; 54*820c1a8dSHiroo HAYASHI } 55*820c1a8dSHiroo HAYASHI 56*820c1a8dSHiroo HAYASHI int glwthread_mutex_trylock(glwthread_mutex_t * mutex)57*820c1a8dSHiroo HAYASHIglwthread_mutex_trylock (glwthread_mutex_t *mutex) 58*820c1a8dSHiroo HAYASHI { 59*820c1a8dSHiroo HAYASHI if (!mutex->guard.done) 60*820c1a8dSHiroo HAYASHI { 61*820c1a8dSHiroo HAYASHI if (InterlockedIncrement (&mutex->guard.started) == 0) 62*820c1a8dSHiroo HAYASHI /* This thread is the first one to need this mutex. Initialize it. */ 63*820c1a8dSHiroo HAYASHI glwthread_mutex_init (mutex); 64*820c1a8dSHiroo HAYASHI else 65*820c1a8dSHiroo HAYASHI { 66*820c1a8dSHiroo HAYASHI /* Don't let mutex->guard.started grow and wrap around. */ 67*820c1a8dSHiroo HAYASHI InterlockedDecrement (&mutex->guard.started); 68*820c1a8dSHiroo HAYASHI /* Let another thread finish initializing this mutex, and let it also 69*820c1a8dSHiroo HAYASHI lock this mutex. */ 70*820c1a8dSHiroo HAYASHI return EBUSY; 71*820c1a8dSHiroo HAYASHI } 72*820c1a8dSHiroo HAYASHI } 73*820c1a8dSHiroo HAYASHI if (!TryEnterCriticalSection (&mutex->lock)) 74*820c1a8dSHiroo HAYASHI return EBUSY; 75*820c1a8dSHiroo HAYASHI return 0; 76*820c1a8dSHiroo HAYASHI } 77*820c1a8dSHiroo HAYASHI 78*820c1a8dSHiroo HAYASHI int glwthread_mutex_unlock(glwthread_mutex_t * mutex)79*820c1a8dSHiroo HAYASHIglwthread_mutex_unlock (glwthread_mutex_t *mutex) 80*820c1a8dSHiroo HAYASHI { 81*820c1a8dSHiroo HAYASHI if (!mutex->guard.done) 82*820c1a8dSHiroo HAYASHI return EINVAL; 83*820c1a8dSHiroo HAYASHI LeaveCriticalSection (&mutex->lock); 84*820c1a8dSHiroo HAYASHI return 0; 85*820c1a8dSHiroo HAYASHI } 86*820c1a8dSHiroo HAYASHI 87*820c1a8dSHiroo HAYASHI int glwthread_mutex_destroy(glwthread_mutex_t * mutex)88*820c1a8dSHiroo HAYASHIglwthread_mutex_destroy (glwthread_mutex_t *mutex) 89*820c1a8dSHiroo HAYASHI { 90*820c1a8dSHiroo HAYASHI if (!mutex->guard.done) 91*820c1a8dSHiroo HAYASHI return EINVAL; 92*820c1a8dSHiroo HAYASHI DeleteCriticalSection (&mutex->lock); 93*820c1a8dSHiroo HAYASHI mutex->guard.done = 0; 94*820c1a8dSHiroo HAYASHI return 0; 95*820c1a8dSHiroo HAYASHI } 96