7
7
8
8
namespace SymEngine {
9
9
10
+ int PyGILState_Check2 (void ) {
11
+ PyThreadState * tstate = _PyThreadState_Current;
12
+ return tstate && (tstate == PyGILState_GetThisThreadState ());
13
+ }
14
+
10
15
// PyModule
11
16
PyModule::PyModule (PyObject* (*to_py)(const RCP<const Basic>), RCP<const Basic> (*from_py)(PyObject*),
12
17
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>
19
24
PyModule::~PyModule (){
20
25
Py_DECREF (zero);
21
26
Py_DECREF (one);
22
- Py_DECREF (minus_one);
27
+ Py_DECREF (minus_one);
23
28
}
24
29
25
30
// PyNumber
@@ -37,8 +42,14 @@ bool PyNumber::__eq__(const Basic &o) const {
37
42
}
38
43
39
44
int PyNumber::compare (const Basic &o) const {
45
+ if (not PyGILState_Check2 ()){
46
+ PyEval_AcquireLock ();
47
+ }
40
48
SYMENGINE_ASSERT (is_a<PyNumber>(o))
41
49
PyObject* o1 = static_cast <const PyNumber &>(o).get_py_object ();
50
+ if (PyGILState_Check2 ()){
51
+ PyEval_ReleaseLock ();
52
+ }
42
53
if (PyObject_RichCompareBool (pyobject_, o1, Py_EQ) == 1 )
43
54
return 0 ;
44
55
return PyObject_RichCompareBool (pyobject_, o1, Py_LT) == 1 ? -1 : 1 ;
@@ -70,6 +81,9 @@ bool PyNumber::is_complex() const {
70
81
71
82
// ! Addition
72
83
RCP<const Number> PyNumber::add (const Number &other) const {
84
+ if (not PyGILState_Check2 ()){
85
+ PyEval_AcquireLock ();
86
+ }
73
87
PyObject *other_p, *result;
74
88
if (is_a<PyNumber>(other)) {
75
89
other_p = static_cast <const PyNumber &>(other).pyobject_ ;
@@ -79,10 +93,16 @@ RCP<const Number> PyNumber::add(const Number &other) const {
79
93
result = PyNumber_Add (pyobject_, other_p);
80
94
Py_XDECREF (other_p);
81
95
}
96
+ if (PyGILState_Check2 ()){
97
+ PyEval_ReleaseLock ();
98
+ }
82
99
return make_rcp<PyNumber>(result, pymodule_);
83
100
}
84
101
// ! Subtraction
85
102
RCP<const Number> PyNumber::sub (const Number &other) const {
103
+ if (not PyGILState_Check2 ()){
104
+ PyEval_AcquireLock ();
105
+ }
86
106
PyObject *other_p, *result;
87
107
if (is_a<PyNumber>(other)) {
88
108
other_p = static_cast <const PyNumber &>(other).pyobject_ ;
@@ -92,9 +112,15 @@ RCP<const Number> PyNumber::sub(const Number &other) const {
92
112
result = PyNumber_Subtract (pyobject_, other_p);
93
113
Py_XDECREF (other_p);
94
114
}
115
+ if (PyGILState_Check2 ()){
116
+ PyEval_ReleaseLock ();
117
+ }
95
118
return make_rcp<PyNumber>(result, pymodule_);
96
119
}
97
120
RCP<const Number> PyNumber::rsub (const Number &other) const {
121
+ if (not PyGILState_Check2 ()){
122
+ PyEval_AcquireLock ();
123
+ }
98
124
PyObject *other_p, *result;
99
125
if (is_a<PyNumber>(other)) {
100
126
other_p = static_cast <const PyNumber &>(other).pyobject_ ;
@@ -104,10 +130,16 @@ RCP<const Number> PyNumber::rsub(const Number &other) const {
104
130
result = PyNumber_Subtract (other_p, pyobject_);
105
131
Py_XDECREF (other_p);
106
132
}
133
+ if (PyGILState_Check2 ()){
134
+ PyEval_ReleaseLock ();
135
+ }
107
136
return make_rcp<PyNumber>(result, pymodule_);
108
137
}
109
138
// ! Multiplication
110
139
RCP<const Number> PyNumber::mul (const Number &other) const {
140
+ if (not PyGILState_Check2 ()){
141
+ PyEval_AcquireLock ();
142
+ }
111
143
PyObject *other_p, *result;
112
144
if (is_a<PyNumber>(other)) {
113
145
other_p = static_cast <const PyNumber &>(other).pyobject_ ;
@@ -117,10 +149,16 @@ RCP<const Number> PyNumber::mul(const Number &other) const {
117
149
result = PyNumber_Multiply (pyobject_, other_p);
118
150
Py_XDECREF (other_p);
119
151
}
152
+ if (PyGILState_Check2 ()){
153
+ PyEval_ReleaseLock ();
154
+ }
120
155
return make_rcp<PyNumber>(result, pymodule_);
121
156
}
122
157
// ! Division
123
158
RCP<const Number> PyNumber::div (const Number &other) const {
159
+ if (not PyGILState_Check2 ()){
160
+ PyEval_AcquireLock ();
161
+ }
124
162
PyObject *other_p, *result;
125
163
if (is_a<PyNumber>(other)) {
126
164
other_p = static_cast <const PyNumber &>(other).pyobject_ ;
@@ -130,9 +168,15 @@ RCP<const Number> PyNumber::div(const Number &other) const {
130
168
result = PyNumber_Divide (pyobject_, other_p);
131
169
Py_XDECREF (other_p);
132
170
}
171
+ if (PyGILState_Check2 ()){
172
+ PyEval_ReleaseLock ();
173
+ }
133
174
return make_rcp<PyNumber>(result, pymodule_);
134
175
}
135
176
RCP<const Number> PyNumber::rdiv (const Number &other) const {
177
+ if (not PyGILState_Check2 ()){
178
+ PyEval_AcquireLock ();
179
+ }
136
180
PyObject *other_p, *result;
137
181
if (is_a<PyNumber>(other)) {
138
182
other_p = static_cast <const PyNumber &>(other).pyobject_ ;
@@ -142,10 +186,16 @@ RCP<const Number> PyNumber::rdiv(const Number &other) const {
142
186
result = PyNumber_Divide (pyobject_, other_p);
143
187
Py_XDECREF (other_p);
144
188
}
189
+ if (PyGILState_Check2 ()){
190
+ PyEval_ReleaseLock ();
191
+ }
145
192
return make_rcp<PyNumber>(result, pymodule_);
146
193
}
147
194
// ! Power
148
195
RCP<const Number> PyNumber::pow (const Number &other) const {
196
+ if (not PyGILState_Check2 ()){
197
+ PyEval_AcquireLock ();
198
+ }
149
199
PyObject *other_p, *result;
150
200
if (is_a<PyNumber>(other)) {
151
201
other_p = static_cast <const PyNumber &>(other).pyobject_ ;
@@ -155,9 +205,15 @@ RCP<const Number> PyNumber::pow(const Number &other) const {
155
205
result = PyNumber_Power (pyobject_, other_p, Py_None);
156
206
Py_XDECREF (other_p);
157
207
}
208
+ if (PyGILState_Check2 ()){
209
+ PyEval_ReleaseLock ();
210
+ }
158
211
return make_rcp<PyNumber>(result, pymodule_);
159
212
}
160
213
RCP<const Number> PyNumber::rpow (const Number &other) const {
214
+ if (not PyGILState_Check2 ()){
215
+ PyEval_AcquireLock ();
216
+ }
161
217
PyObject *other_p, *result;
162
218
if (is_a<PyNumber>(other)) {
163
219
other_p = static_cast <const PyNumber &>(other).pyobject_ ;
@@ -167,6 +223,9 @@ RCP<const Number> PyNumber::rpow(const Number &other) const {
167
223
result = PyNumber_Power (other_p, pyobject_, Py_None);
168
224
Py_XDECREF (other_p);
169
225
}
226
+ if (PyGILState_Check2 ()){
227
+ PyEval_ReleaseLock ();
228
+ }
170
229
return make_rcp<PyNumber>(result, pymodule_);
171
230
}
172
231
@@ -175,6 +234,9 @@ RCP<const Number> PyNumber::eval(long bits) const {
175
234
}
176
235
177
236
std::string PyNumber::__str__ () const {
237
+ if (not PyGILState_Check2 ()){
238
+ PyEval_AcquireLock ();
239
+ }
178
240
PyObject* temp;
179
241
std::string str;
180
242
#if PY_MAJOR_VERSION > 2
@@ -185,6 +247,9 @@ std::string PyNumber::__str__() const {
185
247
str = std::string (PyString_AsString (temp));
186
248
#endif
187
249
Py_XDECREF (temp);
250
+ if (PyGILState_Check2 ()){
251
+ PyEval_ReleaseLock ();
252
+ }
188
253
return str;
189
254
}
190
255
@@ -196,12 +261,18 @@ PyFunctionClass::PyFunctionClass(PyObject *pyobject, std::string name, const RCP
196
261
}
197
262
198
263
PyObject* PyFunctionClass::call (const vec_basic &vec) const {
264
+ if (not PyGILState_Check2 ()){
265
+ PyEval_AcquireLock ();
266
+ }
199
267
PyObject *tuple = PyTuple_New (vec.size ());
200
268
for (unsigned i = 0 ; i < vec.size (); i++) {
201
269
PyTuple_SetItem (tuple, i, pymodule_->to_py_ (vec[i]));
202
270
}
203
271
PyObject* result = PyObject_CallObject (pyobject_, tuple);
204
272
Py_DECREF (tuple);
273
+ if (PyGILState_Check2 ()){
274
+ PyEval_ReleaseLock ();
275
+ }
205
276
return result;
206
277
}
207
278
@@ -240,9 +311,15 @@ RCP<const PyFunctionClass> PyFunction::get_pyfunction_class() const {
240
311
}
241
312
242
313
RCP<const Basic> PyFunction::create (const vec_basic &x) const {
314
+ if (not PyGILState_Check2 ()){
315
+ PyEval_AcquireLock ();
316
+ }
243
317
PyObject* pyobj = pyfunction_class_->call (x);
244
318
RCP<const Basic> result = pyfunction_class_->get_py_module ()->from_py_ (pyobj);
245
319
Py_XDECREF (pyobj);
320
+ if (PyGILState_Check2 ()){
321
+ PyEval_ReleaseLock ();
322
+ }
246
323
return result;
247
324
}
248
325
0 commit comments