Skip to content

Commit ca9d021

Browse files
committed
Acquire GIL in pywrapper.cpp
1 parent bf388b5 commit ca9d021

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

symengine/lib/pywrapper.cpp

+78-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77

88
namespace SymEngine {
99

10+
int PyGILState_Check2(void) {
11+
PyThreadState * tstate = _PyThreadState_Current;
12+
return tstate && (tstate == PyGILState_GetThisThreadState());
13+
}
14+
1015
// PyModule
1116
PyModule::PyModule(PyObject* (*to_py)(const RCP<const Basic>), RCP<const Basic> (*from_py)(PyObject*),
1217
RCP<const Number> (*eval)(PyObject*, long), RCP<const Basic> (*diff)(PyObject*, RCP<const Basic>)) :
@@ -19,7 +24,7 @@ PyModule::PyModule(PyObject* (*to_py)(const RCP<const Basic>), RCP<const Basic>
1924
PyModule::~PyModule(){
2025
Py_DECREF(zero);
2126
Py_DECREF(one);
22-
Py_DECREF(minus_one);
27+
Py_DECREF(minus_one);
2328
}
2429

2530
// PyNumber
@@ -37,8 +42,14 @@ bool PyNumber::__eq__(const Basic &o) const {
3742
}
3843

3944
int PyNumber::compare(const Basic &o) const {
45+
if (not PyGILState_Check2()){
46+
PyEval_AcquireLock();
47+
}
4048
SYMENGINE_ASSERT(is_a<PyNumber>(o))
4149
PyObject* o1 = static_cast<const PyNumber &>(o).get_py_object();
50+
if (PyGILState_Check2()){
51+
PyEval_ReleaseLock();
52+
}
4253
if (PyObject_RichCompareBool(pyobject_, o1, Py_EQ) == 1)
4354
return 0;
4455
return PyObject_RichCompareBool(pyobject_, o1, Py_LT) == 1 ? -1 : 1;
@@ -70,6 +81,9 @@ bool PyNumber::is_complex() const {
7081

7182
//! Addition
7283
RCP<const Number> PyNumber::add(const Number &other) const {
84+
if (not PyGILState_Check2()){
85+
PyEval_AcquireLock();
86+
}
7387
PyObject *other_p, *result;
7488
if (is_a<PyNumber>(other)) {
7589
other_p = static_cast<const PyNumber &>(other).pyobject_;
@@ -79,10 +93,16 @@ RCP<const Number> PyNumber::add(const Number &other) const {
7993
result = PyNumber_Add(pyobject_, other_p);
8094
Py_XDECREF(other_p);
8195
}
96+
if (PyGILState_Check2()){
97+
PyEval_ReleaseLock();
98+
}
8299
return make_rcp<PyNumber>(result, pymodule_);
83100
}
84101
//! Subtraction
85102
RCP<const Number> PyNumber::sub(const Number &other) const {
103+
if (not PyGILState_Check2()){
104+
PyEval_AcquireLock();
105+
}
86106
PyObject *other_p, *result;
87107
if (is_a<PyNumber>(other)) {
88108
other_p = static_cast<const PyNumber &>(other).pyobject_;
@@ -92,9 +112,15 @@ RCP<const Number> PyNumber::sub(const Number &other) const {
92112
result = PyNumber_Subtract(pyobject_, other_p);
93113
Py_XDECREF(other_p);
94114
}
115+
if (PyGILState_Check2()){
116+
PyEval_ReleaseLock();
117+
}
95118
return make_rcp<PyNumber>(result, pymodule_);
96119
}
97120
RCP<const Number> PyNumber::rsub(const Number &other) const {
121+
if (not PyGILState_Check2()){
122+
PyEval_AcquireLock();
123+
}
98124
PyObject *other_p, *result;
99125
if (is_a<PyNumber>(other)) {
100126
other_p = static_cast<const PyNumber &>(other).pyobject_;
@@ -104,10 +130,16 @@ RCP<const Number> PyNumber::rsub(const Number &other) const {
104130
result = PyNumber_Subtract(other_p, pyobject_);
105131
Py_XDECREF(other_p);
106132
}
133+
if (PyGILState_Check2()){
134+
PyEval_ReleaseLock();
135+
}
107136
return make_rcp<PyNumber>(result, pymodule_);
108137
}
109138
//! Multiplication
110139
RCP<const Number> PyNumber::mul(const Number &other) const {
140+
if (not PyGILState_Check2()){
141+
PyEval_AcquireLock();
142+
}
111143
PyObject *other_p, *result;
112144
if (is_a<PyNumber>(other)) {
113145
other_p = static_cast<const PyNumber &>(other).pyobject_;
@@ -117,10 +149,16 @@ RCP<const Number> PyNumber::mul(const Number &other) const {
117149
result = PyNumber_Multiply(pyobject_, other_p);
118150
Py_XDECREF(other_p);
119151
}
152+
if (PyGILState_Check2()){
153+
PyEval_ReleaseLock();
154+
}
120155
return make_rcp<PyNumber>(result, pymodule_);
121156
}
122157
//! Division
123158
RCP<const Number> PyNumber::div(const Number &other) const {
159+
if (not PyGILState_Check2()){
160+
PyEval_AcquireLock();
161+
}
124162
PyObject *other_p, *result;
125163
if (is_a<PyNumber>(other)) {
126164
other_p = static_cast<const PyNumber &>(other).pyobject_;
@@ -130,9 +168,15 @@ RCP<const Number> PyNumber::div(const Number &other) const {
130168
result = PyNumber_Divide(pyobject_, other_p);
131169
Py_XDECREF(other_p);
132170
}
171+
if (PyGILState_Check2()){
172+
PyEval_ReleaseLock();
173+
}
133174
return make_rcp<PyNumber>(result, pymodule_);
134175
}
135176
RCP<const Number> PyNumber::rdiv(const Number &other) const {
177+
if (not PyGILState_Check2()){
178+
PyEval_AcquireLock();
179+
}
136180
PyObject *other_p, *result;
137181
if (is_a<PyNumber>(other)) {
138182
other_p = static_cast<const PyNumber &>(other).pyobject_;
@@ -142,10 +186,16 @@ RCP<const Number> PyNumber::rdiv(const Number &other) const {
142186
result = PyNumber_Divide(pyobject_, other_p);
143187
Py_XDECREF(other_p);
144188
}
189+
if (PyGILState_Check2()){
190+
PyEval_ReleaseLock();
191+
}
145192
return make_rcp<PyNumber>(result, pymodule_);
146193
}
147194
//! Power
148195
RCP<const Number> PyNumber::pow(const Number &other) const {
196+
if (not PyGILState_Check2()){
197+
PyEval_AcquireLock();
198+
}
149199
PyObject *other_p, *result;
150200
if (is_a<PyNumber>(other)) {
151201
other_p = static_cast<const PyNumber &>(other).pyobject_;
@@ -155,9 +205,15 @@ RCP<const Number> PyNumber::pow(const Number &other) const {
155205
result = PyNumber_Power(pyobject_, other_p, Py_None);
156206
Py_XDECREF(other_p);
157207
}
208+
if (PyGILState_Check2()){
209+
PyEval_ReleaseLock();
210+
}
158211
return make_rcp<PyNumber>(result, pymodule_);
159212
}
160213
RCP<const Number> PyNumber::rpow(const Number &other) const {
214+
if (not PyGILState_Check2()){
215+
PyEval_AcquireLock();
216+
}
161217
PyObject *other_p, *result;
162218
if (is_a<PyNumber>(other)) {
163219
other_p = static_cast<const PyNumber &>(other).pyobject_;
@@ -167,6 +223,9 @@ RCP<const Number> PyNumber::rpow(const Number &other) const {
167223
result = PyNumber_Power(other_p, pyobject_, Py_None);
168224
Py_XDECREF(other_p);
169225
}
226+
if (PyGILState_Check2()){
227+
PyEval_ReleaseLock();
228+
}
170229
return make_rcp<PyNumber>(result, pymodule_);
171230
}
172231

@@ -175,6 +234,9 @@ RCP<const Number> PyNumber::eval(long bits) const {
175234
}
176235

177236
std::string PyNumber::__str__() const {
237+
if (not PyGILState_Check2()){
238+
PyEval_AcquireLock();
239+
}
178240
PyObject* temp;
179241
std::string str;
180242
#if PY_MAJOR_VERSION > 2
@@ -185,6 +247,9 @@ std::string PyNumber::__str__() const {
185247
str = std::string(PyString_AsString(temp));
186248
#endif
187249
Py_XDECREF(temp);
250+
if (PyGILState_Check2()){
251+
PyEval_ReleaseLock();
252+
}
188253
return str;
189254
}
190255

@@ -196,12 +261,18 @@ PyFunctionClass::PyFunctionClass(PyObject *pyobject, std::string name, const RCP
196261
}
197262

198263
PyObject* PyFunctionClass::call(const vec_basic &vec) const {
264+
if (not PyGILState_Check2()){
265+
PyEval_AcquireLock();
266+
}
199267
PyObject *tuple = PyTuple_New(vec.size());
200268
for (unsigned i = 0; i < vec.size(); i++) {
201269
PyTuple_SetItem(tuple, i, pymodule_->to_py_(vec[i]));
202270
}
203271
PyObject* result = PyObject_CallObject(pyobject_, tuple);
204272
Py_DECREF(tuple);
273+
if (PyGILState_Check2()){
274+
PyEval_ReleaseLock();
275+
}
205276
return result;
206277
}
207278

@@ -240,9 +311,15 @@ RCP<const PyFunctionClass> PyFunction::get_pyfunction_class() const {
240311
}
241312

242313
RCP<const Basic> PyFunction::create(const vec_basic &x) const {
314+
if (not PyGILState_Check2()){
315+
PyEval_AcquireLock();
316+
}
243317
PyObject* pyobj = pyfunction_class_->call(x);
244318
RCP<const Basic> result = pyfunction_class_->get_py_module()->from_py_(pyobj);
245319
Py_XDECREF(pyobj);
320+
if (PyGILState_Check2()){
321+
PyEval_ReleaseLock();
322+
}
246323
return result;
247324
}
248325

0 commit comments

Comments
 (0)