Skip to content

Commit c4a01ac

Browse files
committed
pipeline: give Mutex and ReMutex more Pythonic semantics
This allows using mutices in with-blocks and wraps up the functionality of acquire() and try_acquire() into a single acquire(blocking=True). Furthermore, the GIL is no longer released in cases of no contention.
1 parent 2e9bd0f commit c4a01ac

File tree

12 files changed

+235
-29
lines changed

12 files changed

+235
-29
lines changed

direct/src/stdpy/threading.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,6 @@ class Lock(core.Mutex):
201201
def __init__(self, name = "PythonLock"):
202202
core.Mutex.__init__(self, name)
203203

204-
def acquire(self, blocking = True):
205-
if blocking:
206-
core.Mutex.acquire(self)
207-
return True
208-
else:
209-
return core.Mutex.tryAcquire(self)
210-
211-
__enter__ = acquire
212-
213-
def __exit__(self, t, v, tb):
214-
self.release()
215204

216205
class RLock(core.ReMutex):
217206
""" This class provides a wrapper around Panda's ReMutex object.
@@ -221,18 +210,6 @@ class RLock(core.ReMutex):
221210
def __init__(self, name = "PythonRLock"):
222211
core.ReMutex.__init__(self, name)
223212

224-
def acquire(self, blocking = True):
225-
if blocking:
226-
core.ReMutex.acquire(self)
227-
return True
228-
else:
229-
return core.ReMutex.tryAcquire(self)
230-
231-
__enter__ = acquire
232-
233-
def __exit__(self, t, v, tb):
234-
self.release()
235-
236213

237214
class Condition(core.ConditionVarFull):
238215
""" This class provides a wrapper around Panda's ConditionVarFull

panda/src/pipeline/mutexDebug.I

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ acquire(Thread *current_thread) const {
7070
/**
7171
* Returns immediately, with a true value indicating the mutex has been
7272
* acquired, and false indicating it has not.
73+
*
74+
* @deprecated Python users should use acquire(False), C++ users try_lock()
7375
*/
7476
INLINE bool MutexDebug::
7577
try_acquire(Thread *current_thread) const {

panda/src/pipeline/mutexDirect.I

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ acquire() const {
6060
/**
6161
* Returns immediately, with a true value indicating the mutex has been
6262
* acquired, and false indicating it has not.
63+
*
64+
* @deprecated Python users should use acquire(False), C++ users try_lock()
6365
*/
6466
INLINE bool MutexDirect::
6567
try_acquire() const {

panda/src/pipeline/pmutex.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ class EXPCL_PANDA_PIPELINE Mutex : public MutexDirect
4949

5050
void operator = (const Mutex &copy) = delete;
5151

52+
EXTENSION(bool acquire(bool blocking=true) const);
53+
EXTENSION(bool __enter__());
54+
EXTENSION(void __exit__(PyObject *, PyObject *, PyObject *));
55+
5256
public:
5357
// This is a global mutex set aside for the purpose of protecting Notify
5458
// messages from being interleaved between threads.

panda/src/pipeline/pmutex_ext.I

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* PANDA 3D SOFTWARE
3+
* Copyright (c) Carnegie Mellon University. All rights reserved.
4+
*
5+
* All use of this software is subject to the terms of the revised BSD
6+
* license. You should have received a copy of this license along
7+
* with this source code in a file named "LICENSE."
8+
*
9+
* @file pmutex_ext.h
10+
* @author rdb
11+
* @date 2019-05-12
12+
*/
13+
14+
/**
15+
* Acquires the mutex.
16+
*/
17+
INLINE bool Extension<Mutex>::
18+
acquire(bool blocking) const {
19+
if (_this->try_lock()) {
20+
return true;
21+
}
22+
23+
if (!blocking) {
24+
return false;
25+
}
26+
27+
// Release the GIL while we are waiting for the lock.
28+
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
29+
PyThreadState *_save;
30+
Py_UNBLOCK_THREADS
31+
_this->lock();
32+
Py_BLOCK_THREADS
33+
#else
34+
_this->lock();
35+
#endif
36+
return true;
37+
}
38+
39+
/**
40+
* Acquires the mutex.
41+
*/
42+
INLINE bool Extension<Mutex>::
43+
__enter__() {
44+
return acquire(true);
45+
}
46+
47+
/**
48+
* Releases the mutex.
49+
*/
50+
INLINE void Extension<Mutex>::
51+
__exit__(PyObject *, PyObject *, PyObject *) {
52+
_this->unlock();
53+
}

panda/src/pipeline/pmutex_ext.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* PANDA 3D SOFTWARE
3+
* Copyright (c) Carnegie Mellon University. All rights reserved.
4+
*
5+
* All use of this software is subject to the terms of the revised BSD
6+
* license. You should have received a copy of this license along
7+
* with this source code in a file named "LICENSE."
8+
*
9+
* @file pmutex_ext.h
10+
* @author rdb
11+
* @date 2019-05-12
12+
*/
13+
14+
#ifndef PMUTEX_EXT_H
15+
#define PMUTEX_EXT_H
16+
17+
#include "dtoolbase.h"
18+
19+
#ifdef HAVE_PYTHON
20+
21+
#include "extension.h"
22+
#include "pmutex.h"
23+
#include "py_panda.h"
24+
25+
/**
26+
* This class defines the extension methods for Mutex, which are called
27+
* instead of any C++ methods with the same prototype.
28+
*/
29+
template<>
30+
class Extension<Mutex> : public ExtensionBase<Mutex> {
31+
public:
32+
INLINE bool acquire(bool blocking) const;
33+
INLINE bool __enter__();
34+
INLINE void __exit__(PyObject *, PyObject *, PyObject *);
35+
};
36+
37+
#include "pmutex_ext.I"
38+
39+
#endif // HAVE_PYTHON
40+
41+
#endif // PMUTEX_EXT_H

panda/src/pipeline/reMutex.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ class EXPCL_PANDA_PIPELINE ReMutex : public ReMutexDirect
4242
~ReMutex() = default;
4343

4444
void operator = (const ReMutex &copy) = delete;
45+
46+
EXTENSION(bool acquire(bool blocking=true) const);
47+
EXTENSION(bool __enter__());
48+
EXTENSION(void __exit__(PyObject *, PyObject *, PyObject *));
4549
};
4650

4751
#include "reMutex.I"

panda/src/pipeline/reMutexDirect.I

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ acquire(Thread *current_thread) const {
105105
/**
106106
* Returns immediately, with a true value indicating the mutex has been
107107
* acquired, and false indicating it has not.
108+
*
109+
* @deprecated Python users should use acquire(False), C++ users try_lock()
108110
*/
109111
INLINE bool ReMutexDirect::
110112
try_acquire() const {
@@ -119,6 +121,8 @@ try_acquire() const {
119121
/**
120122
* Returns immediately, with a true value indicating the mutex has been
121123
* acquired, and false indicating it has not.
124+
*
125+
* @deprecated Python users should use acquire(False), C++ users try_lock()
122126
*/
123127
INLINE bool ReMutexDirect::
124128
try_acquire(Thread *current_thread) const {

panda/src/pipeline/reMutex_ext.I

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* PANDA 3D SOFTWARE
3+
* Copyright (c) Carnegie Mellon University. All rights reserved.
4+
*
5+
* All use of this software is subject to the terms of the revised BSD
6+
* license. You should have received a copy of this license along
7+
* with this source code in a file named "LICENSE."
8+
*
9+
* @file pmutex_ext.h
10+
* @author rdb
11+
* @date 2019-05-12
12+
*/
13+
14+
/**
15+
* Acquires the mutex.
16+
*/
17+
INLINE bool Extension<ReMutex>::
18+
acquire(bool blocking) const {
19+
if (_this->try_lock()) {
20+
return true;
21+
}
22+
23+
if (!blocking) {
24+
return false;
25+
}
26+
27+
// Release the GIL while we are waiting for the lock.
28+
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
29+
PyThreadState *_save;
30+
Py_UNBLOCK_THREADS
31+
_this->lock();
32+
Py_BLOCK_THREADS
33+
#else
34+
_this->lock();
35+
#endif
36+
return true;
37+
}
38+
39+
/**
40+
* Acquires the mutex.
41+
*/
42+
INLINE bool Extension<ReMutex>::
43+
__enter__() {
44+
return acquire(true);
45+
}
46+
47+
/**
48+
* Releases the mutex.
49+
*/
50+
INLINE void Extension<ReMutex>::
51+
__exit__(PyObject *, PyObject *, PyObject *) {
52+
_this->unlock();
53+
}

panda/src/pipeline/reMutex_ext.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* PANDA 3D SOFTWARE
3+
* Copyright (c) Carnegie Mellon University. All rights reserved.
4+
*
5+
* All use of this software is subject to the terms of the revised BSD
6+
* license. You should have received a copy of this license along
7+
* with this source code in a file named "LICENSE."
8+
*
9+
* @file remutex_ext.h
10+
* @author rdb
11+
* @date 2019-05-12
12+
*/
13+
14+
#ifndef REMUTEX_EXT_H
15+
#define REMUTEX_EXT_H
16+
17+
#include "dtoolbase.h"
18+
19+
#ifdef HAVE_PYTHON
20+
21+
#include "extension.h"
22+
#include "reMutex.h"
23+
#include "py_panda.h"
24+
25+
/**
26+
* This class defines the extension methods for ReMutex, which are called
27+
* instead of any C++ methods with the same prototype.
28+
*/
29+
template<>
30+
class Extension<ReMutex> : public ExtensionBase<ReMutex> {
31+
public:
32+
INLINE bool acquire(bool blocking) const;
33+
INLINE bool __enter__();
34+
INLINE void __exit__(PyObject *, PyObject *, PyObject *);
35+
};
36+
37+
#include "reMutex_ext.I"
38+
39+
#endif // HAVE_PYTHON
40+
41+
#endif // REMUTEX_EXT_H

0 commit comments

Comments
 (0)