7
7
#include < mutex>
8
8
#include < set>
9
9
10
- std::unique_ptr<std:: mutex> _lock_set_mutex = std::make_unique<std::mutex>() ;
10
+ std::mutex _lock_set_mutex;
11
11
12
12
// ----------------------------------------------------------------------------
13
13
// Lock class
@@ -23,19 +23,18 @@ typedef struct lock
23
23
std::unique_ptr<std::timed_mutex> _mutex = nullptr ;
24
24
} Lock;
25
25
26
- std::set<Lock*> lock_set; // Global set of locks for reset after fork
26
+ std::set<Lock*> lock_set;
27
27
28
28
// ----------------------------------------------------------------------------
29
29
static int
30
- Lock_init (Lock* self, PyObject* args, PyObject* kwargs)
30
+ Lock_init (Lock* self, PyObject* Py_UNUSED ( args) , PyObject* Py_UNUSED( kwargs) )
31
31
{
32
32
self->_mutex = std::make_unique<std::timed_mutex>();
33
33
34
- // Register the lock for reset after fork
35
34
{
36
35
AllowThreads _;
37
36
38
- std::lock_guard<std::mutex> guard (* _lock_set_mutex);
37
+ std::lock_guard<std::mutex> guard (_lock_set_mutex);
39
38
40
39
lock_set.insert (self);
41
40
}
@@ -51,7 +50,7 @@ Lock_dealloc(Lock* self)
51
50
{
52
51
AllowThreads _;
53
52
54
- std::lock_guard<std::mutex> guard (* _lock_set_mutex);
53
+ std::lock_guard<std::mutex> guard (_lock_set_mutex);
55
54
56
55
lock_set.erase (self);
57
56
}
@@ -109,7 +108,7 @@ Lock_release(Lock* self)
109
108
}
110
109
111
110
self->_mutex ->unlock ();
112
- self->_locked = 0 ; // Reset the lock state
111
+ self->_locked = 0 ;
113
112
114
113
Py_RETURN_NONE;
115
114
}
@@ -127,7 +126,7 @@ Lock_locked(Lock* self)
127
126
128
127
// ----------------------------------------------------------------------------
129
128
static PyObject*
130
- Lock_enter (Lock* self, PyObject* args, PyObject* kwargs )
129
+ Lock_enter (Lock* self)
131
130
{
132
131
AllowThreads _;
133
132
@@ -140,7 +139,7 @@ Lock_enter(Lock* self, PyObject* args, PyObject* kwargs)
140
139
141
140
// ----------------------------------------------------------------------------
142
141
static PyObject*
143
- Lock_exit (Lock* self, PyObject* args, PyObject* kwargs)
142
+ Lock_exit (Lock* self, PyObject* Py_UNUSED ( args) , PyObject* Py_UNUSED( kwargs) )
144
143
{
145
144
// This method is called when the lock is used in a "with" statement
146
145
if (Lock_release (self) == NULL ) {
@@ -150,13 +149,6 @@ Lock_exit(Lock* self, PyObject* args, PyObject* kwargs)
150
149
Py_RETURN_FALSE;
151
150
}
152
151
153
- static inline void
154
- Lock_reset (Lock* self)
155
- {
156
- self->_mutex = std::make_unique<std::timed_mutex>();
157
- self->_locked = 0 ;
158
- }
159
-
160
152
// ----------------------------------------------------------------------------
161
153
static PyMethodDef Lock_methods[] = {
162
154
{ " acquire" , (PyCFunction)Lock_acquire, METH_VARARGS | METH_KEYWORDS, " Acquire the lock with an optional timeout" },
@@ -200,19 +192,18 @@ typedef struct rlock
200
192
std::unique_ptr<std::recursive_timed_mutex> _mutex = nullptr ;
201
193
} RLock;
202
194
203
- std::set<RLock*> rlock_set; // Global set of re-entrant locks for reset after fork
195
+ std::set<RLock*> rlock_set;
204
196
205
197
// ----------------------------------------------------------------------------
206
198
static int
207
- RLock_init (RLock* self, PyObject* args, PyObject* kwargs)
199
+ RLock_init (RLock* self, PyObject* Py_UNUSED ( args) , PyObject* Py_UNUSED( kwargs) )
208
200
{
209
201
self->_mutex = std::make_unique<std::recursive_timed_mutex>();
210
202
211
- // Register the re-entrant lock for reset after fork
212
203
{
213
204
AllowThreads _;
214
205
215
- std::lock_guard<std::mutex> guard (* _lock_set_mutex);
206
+ std::lock_guard<std::mutex> guard (_lock_set_mutex);
216
207
217
208
rlock_set.insert (self);
218
209
}
@@ -227,7 +218,7 @@ RLock_dealloc(RLock* self)
227
218
{
228
219
AllowThreads _;
229
220
230
- std::lock_guard<std::mutex> guard (* _lock_set_mutex);
221
+ std::lock_guard<std::mutex> guard (_lock_set_mutex);
231
222
232
223
rlock_set.erase (self);
233
224
}
@@ -303,7 +294,7 @@ RLock_locked(RLock* self)
303
294
304
295
// ----------------------------------------------------------------------------
305
296
static PyObject*
306
- RLock_enter (RLock* self, PyObject* args, PyObject* kwargs )
297
+ RLock_enter (RLock* self)
307
298
{
308
299
AllowThreads _;
309
300
@@ -316,7 +307,7 @@ RLock_enter(RLock* self, PyObject* args, PyObject* kwargs)
316
307
317
308
// ----------------------------------------------------------------------------
318
309
static PyObject*
319
- RLock_exit (RLock* self, PyObject* args, PyObject* kwargs)
310
+ RLock_exit (RLock* self, PyObject* Py_UNUSED ( args) , PyObject* Py_UNUSED( kwargs) )
320
311
{
321
312
// This method is called when the lock is used in a "with" statement
322
313
if (RLock_release (self) == NULL ) {
@@ -326,13 +317,6 @@ RLock_exit(RLock* self, PyObject* args, PyObject* kwargs)
326
317
Py_RETURN_FALSE;
327
318
}
328
319
329
- static inline void
330
- RLock_reset (RLock* self)
331
- {
332
- self->_mutex = std::make_unique<std::recursive_timed_mutex>();
333
- self->_locked = 0 ;
334
- }
335
-
336
320
// ----------------------------------------------------------------------------
337
321
static PyMethodDef RLock_methods[] = {
338
322
{ " acquire" ,
@@ -367,21 +351,41 @@ static PyTypeObject RLockType = {
367
351
368
352
// ----------------------------------------------------------------------------
369
353
static PyObject*
370
- lock_reset_locks (PyObject* Py_UNUSED (self), PyObject* Py_UNUSED(args))
354
+ lock_acquire_all (PyObject* Py_UNUSED (self), PyObject* Py_UNUSED(args))
371
355
{
372
- // Reset all locks that have been registered for reset after a fork. This
373
- // MUST be called in a single-thread scenario only, e.g. soon after the
374
- // fork.
356
+ {
357
+ AllowThreads _;
358
+
359
+ _lock_set_mutex.lock ();
360
+
361
+ for (Lock* lock : lock_set) {
362
+ self->_mutex ->lock ();
363
+ self->_locked = 1 ;
364
+ }
365
+
366
+ for (RLock* rlock : rlock_set) {
367
+ rlock->_mutex ->lock ();
368
+ rlock->_locked ++;
369
+ }
370
+ }
371
+
372
+ Py_RETURN_NONE;
373
+ }
374
+
375
+ // ----------------------------------------------------------------------------
376
+ static PyObject*
377
+ lock_release_all (PyObject* Py_UNUSED (self), PyObject* Py_UNUSED(args))
378
+ {
379
+
375
380
for (Lock* lock : lock_set) {
376
- Lock_reset (lock);
381
+ Lock_exit (lock, NULL , NULL );
377
382
}
378
383
379
384
for (RLock* rlock : rlock_set) {
380
- RLock_reset (rlock);
385
+ RLock_exit (rlock, NULL , NULL );
381
386
}
382
387
383
- // Reset the lock set mutex too!
384
- _lock_set_mutex = std::make_unique<std::mutex>();
388
+ _lock_set_mutex.unlock ();
385
389
386
390
Py_RETURN_NONE;
387
391
}
0 commit comments