summaryrefslogtreecommitdiffstats
path: root/gl/windows-mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/windows-mutex.c')
-rw-r--r--gl/windows-mutex.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/gl/windows-mutex.c b/gl/windows-mutex.c
index b112e13b..87b75735 100644
--- a/gl/windows-mutex.c
+++ b/gl/windows-mutex.c
@@ -1,5 +1,5 @@
1/* Plain mutexes (native Windows implementation). 1/* Plain mutexes (native Windows implementation).
2 Copyright (C) 2005-2024 Free Software Foundation, Inc. 2 Copyright (C) 2005-2025 Free Software Foundation, Inc.
3 3
4 This file is free software: you can redistribute it and/or modify 4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as 5 it under the terms of the GNU Lesser General Public License as
@@ -23,10 +23,12 @@
23#include "windows-mutex.h" 23#include "windows-mutex.h"
24 24
25#include <errno.h> 25#include <errno.h>
26#include <stdlib.h>
26 27
27void 28void
28glwthread_mutex_init (glwthread_mutex_t *mutex) 29glwthread_mutex_init (glwthread_mutex_t *mutex)
29{ 30{
31 mutex->owner = 0;
30 InitializeCriticalSection (&mutex->lock); 32 InitializeCriticalSection (&mutex->lock);
31 mutex->guard.done = 1; 33 mutex->guard.done = 1;
32} 34}
@@ -49,7 +51,13 @@ glwthread_mutex_lock (glwthread_mutex_t *mutex)
49 Sleep (0); 51 Sleep (0);
50 } 52 }
51 } 53 }
54 /* If this thread already owns the mutex, POSIX pthread_mutex_lock() is
55 required to deadlock here. But let's not do that on purpose. */
52 EnterCriticalSection (&mutex->lock); 56 EnterCriticalSection (&mutex->lock);
57 {
58 DWORD self = GetCurrentThreadId ();
59 mutex->owner = self;
60 }
53 return 0; 61 return 0;
54} 62}
55 63
@@ -72,6 +80,21 @@ glwthread_mutex_trylock (glwthread_mutex_t *mutex)
72 } 80 }
73 if (!TryEnterCriticalSection (&mutex->lock)) 81 if (!TryEnterCriticalSection (&mutex->lock))
74 return EBUSY; 82 return EBUSY;
83 {
84 DWORD self = GetCurrentThreadId ();
85 /* TryEnterCriticalSection succeeded. This means that the mutex was either
86 previously unlocked (and thus mutex->owner == 0) or previously locked by
87 this thread (and thus mutex->owner == self). Since the mutex is meant to
88 be plain, we need to fail in the latter case. */
89 if (mutex->owner == self)
90 {
91 LeaveCriticalSection (&mutex->lock);
92 return EBUSY;
93 }
94 if (mutex->owner != 0)
95 abort ();
96 mutex->owner = self;
97 }
75 return 0; 98 return 0;
76} 99}
77 100
@@ -80,6 +103,7 @@ glwthread_mutex_unlock (glwthread_mutex_t *mutex)
80{ 103{
81 if (!mutex->guard.done) 104 if (!mutex->guard.done)
82 return EINVAL; 105 return EINVAL;
106 mutex->owner = 0;
83 LeaveCriticalSection (&mutex->lock); 107 LeaveCriticalSection (&mutex->lock);
84 return 0; 108 return 0;
85} 109}