1 /**
2     Win32 Implementation for nulib.threading.internal.mutex
3 
4     Copyright:
5         Copyright © 2025, Kitsunebi Games
6         Copyright © 2025, Inochi2D Project
7     
8     License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
9     Authors:   Luna Nielsen
10 */
11 module nulib.win32.threading.mutex;
12 import nulib.threading.internal.mutex;
13 import nulib.win32.common;
14 import numem;
15 
16 /**
17     Native implementation of a mutually exclusive lock.
18 */
19 class Win32Mutex : NativeMutex {
20 private:
21     CRITICAL_SECTION* handle_;
22 
23 public:
24 @nogc:
25 
26     /// Destructor
27     ~this() nothrow {
28         DeleteCriticalSection(handle_);
29         nu_free(handle_);
30     }
31 
32     /**
33         Constructs a mutex.
34     */
35     this() nothrow {
36         this.handle_ = cast(CRITICAL_SECTION*)nu_malloc(CRITICAL_SECTION.sizeof);
37 
38         // Cargo-culting the spin-count in WTF::Lock
39         // See: https://webkit.org/blog/6161/locking-in-webkit/
40         cast(void)InitializeCriticalSectionAndSpinCount(handle_, 40);
41     }
42 
43     /**
44         Increments the internal lock counter.
45     */
46     override
47     void lock() nothrow @trusted {
48         EnterCriticalSection(handle_);
49     }
50 
51     /**
52         Tries to increment the internal lock counter.
53 
54         Returns:
55             $(D true) if the mutex was locked,
56             $(D false) otherwise.
57     */
58     override
59     bool tryLock() nothrow @trusted {
60         return TryEnterCriticalSection(handle_) != 0;
61     }
62 
63     /**
64         Decrements the internal lock counter,
65         If the counter reaches 0, the lock is released.
66     */
67     override
68     void unlock() nothrow @trusted {
69         LeaveCriticalSection(handle_);
70     }
71 }
72 
73 extern(C) export
74 NativeMutex _nu_mutex_new() @trusted @nogc nothrow {
75     return nogc_new!Win32Mutex();
76 }
77 
78 //
79 //          BINDINGS
80 //
81 extern(Windows) @nogc nothrow:
82 
83 /// A critical section object.
84 struct CRITICAL_SECTION {
85     void*   DebugInfo;
86     int     LockCount;
87     int     RecursionCount;
88     void*   OwningThread;
89     void*   LockSemaphore;
90     size_t  SpinCount;
91 }
92 
93 extern void DeleteCriticalSection(CRITICAL_SECTION*);
94 extern uint InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION*, uint);
95 extern void EnterCriticalSection(CRITICAL_SECTION*);
96 extern void LeaveCriticalSection(CRITICAL_SECTION*);
97 extern uint TryEnterCriticalSection(CRITICAL_SECTION*);