@@ -43,6 +43,17 @@ Lock_init(Lock* self, PyObject* args, PyObject* kwargs)
43
43
return 0 ;
44
44
}
45
45
46
+ // ----------------------------------------------------------------------------
47
+ static inline void
48
+ _Lock_maybe_leak (Lock* self)
49
+ {
50
+ // This function is used to ensure that the mutex is not leaked if it is
51
+ // still locked when the lock object is deallocated.
52
+ if (self->_locked ) {
53
+ self->_mutex .release (); // DEV: This releases the unique_ptr, not the mutex!
54
+ }
55
+ }
56
+
46
57
// ----------------------------------------------------------------------------
47
58
static void
48
59
Lock_dealloc (Lock* self)
@@ -56,6 +67,8 @@ Lock_dealloc(Lock* self)
56
67
lock_set.erase (self);
57
68
}
58
69
70
+ _Lock_maybe_leak (self);
71
+
59
72
self->_mutex = nullptr ;
60
73
61
74
Py_TYPE (self)->tp_free ((PyObject*)self);
@@ -153,6 +166,7 @@ Lock_exit(Lock* self, PyObject* args, PyObject* kwargs)
153
166
static inline void
154
167
Lock_reset (Lock* self)
155
168
{
169
+ _Lock_maybe_leak (self);
156
170
self->_mutex = std::make_unique<std::timed_mutex>();
157
171
self->_locked = 0 ;
158
172
}
@@ -220,6 +234,17 @@ RLock_init(RLock* self, PyObject* args, PyObject* kwargs)
220
234
return 0 ;
221
235
}
222
236
237
+ // ----------------------------------------------------------------------------
238
+ static inline void
239
+ _RLock_maybe_leak (RLock* self)
240
+ {
241
+ // This function is used to ensure that the mutex is not leaked if it is
242
+ // still locked when the re-entrant lock object is deallocated.
243
+ if (self->_locked ) {
244
+ self->_mutex .release (); // DEV: This releases the unique_ptr, not the mutex!
245
+ }
246
+ }
247
+
223
248
// ----------------------------------------------------------------------------
224
249
static void
225
250
RLock_dealloc (RLock* self)
@@ -232,6 +257,7 @@ RLock_dealloc(RLock* self)
232
257
rlock_set.erase (self);
233
258
}
234
259
260
+ _RLock_maybe_leak (self);
235
261
self->_mutex = nullptr ;
236
262
237
263
Py_TYPE (self)->tp_free ((PyObject*)self);
@@ -329,6 +355,7 @@ RLock_exit(RLock* self, PyObject* args, PyObject* kwargs)
329
355
static inline void
330
356
RLock_reset (RLock* self)
331
357
{
358
+ _RLock_maybe_leak (self);
332
359
self->_mutex = std::make_unique<std::recursive_timed_mutex>();
333
360
self->_locked = 0 ;
334
361
}
0 commit comments