@@ -19,6 +19,8 @@ const PyJuliaBase_Type = Ref(C.PyNULL)
19
19
const PYJLVALUES = []
20
20
# unused indices in PYJLVALUES
21
21
const PYJLFREEVALUES = Int[]
22
+ # Thread safety for PYJLVALUES and PYJLFREEVALUES
23
+ const PYJLVALUES_LOCK = Threads. SpinLock ()
22
24
23
25
function _pyjl_new (t:: C.PyPtr , :: C.PyPtr , :: C.PyPtr )
24
26
o = ccall (UnsafePtr {C.PyTypeObject} (t). alloc[! ], C. PyPtr, (C. PyPtr, C. Py_ssize_t), t, 0 )
31
33
function _pyjl_dealloc (o:: C.PyPtr )
32
34
idx = UnsafePtr {PyJuliaValueObject} (o). value[]
33
35
if idx != 0
34
- PYJLVALUES[idx] = nothing
35
- push! (PYJLFREEVALUES, idx)
36
+ Base. @lock PYJLVALUES_LOCK begin
37
+ PYJLVALUES[idx] = nothing
38
+ push! (PYJLFREEVALUES, idx)
39
+ end
36
40
end
37
41
UnsafePtr {PyJuliaValueObject} (o). weaklist[! ] == C. PyNULL || C. PyObject_ClearWeakRefs (o)
38
42
ccall (UnsafePtr {C.PyTypeObject} (C. Py_Type (o)). free[! ], Cvoid, (C. PyPtr,), o)
39
43
nothing
40
44
end
41
45
42
46
const PYJLMETHODS = Vector {Any} ()
47
+ const PYJLMETHODS_LOCK = Threads. SpinLock ()
43
48
44
49
function PyJulia_MethodNum (f)
45
50
@nospecialize f
46
- push! (PYJLMETHODS, f)
47
- return length (PYJLMETHODS)
51
+ Base. @lock PYJLMETHODS_LOCK begin
52
+ push! (PYJLMETHODS, f)
53
+ return length (PYJLMETHODS)
54
+ end
48
55
end
49
56
50
57
function _pyjl_isnull (o:: C.PyPtr , :: C.PyPtr )
@@ -58,12 +65,13 @@ function _pyjl_callmethod(o::C.PyPtr, args::C.PyPtr)
58
65
@assert nargs > 0
59
66
num = C. PyLong_AsLongLong (C. PyTuple_GetItem (args, 0 ))
60
67
num == - 1 && return C. PyNULL
61
- f = PYJLMETHODS[num]
68
+ f = Base . @lock PYJLMETHODS_LOCK PYJLMETHODS[num]
62
69
# this form gets defined in jlwrap/base.jl
63
70
return _pyjl_callmethod (f, o, args, nargs):: C.PyPtr
64
71
end
65
72
66
73
const PYJLBUFCACHE = Dict {Ptr{Cvoid},Any} ()
74
+ const PYJLBUFCACHE_LOCK = Threads. SpinLock ()
67
75
68
76
@kwdef struct PyBufferInfo{N}
69
77
# data
@@ -177,7 +185,9 @@ function _pyjl_get_buffer_impl(
177
185
178
186
# internal
179
187
cptr = Base. pointer_from_objref (c)
180
- PYJLBUFCACHE[cptr] = c
188
+ Base. @lock PYJLBUFCACHE_LOCK begin
189
+ PYJLBUFCACHE[cptr] = c
190
+ end
181
191
b. internal[] = cptr
182
192
183
193
# obj
@@ -195,7 +205,7 @@ function _pyjl_get_buffer(o::C.PyPtr, buf::Ptr{C.Py_buffer}, flags::Cint)
195
205
C. Py_DecRef (num_)
196
206
num == - 1 && return Cint (- 1 )
197
207
try
198
- f = PYJLMETHODS[num]
208
+ f = Base . @lock PYJLMETHODS_LOCK PYJLMETHODS[num]
199
209
x = PyJuliaValue_GetValue (o)
200
210
return _pyjl_get_buffer_impl (o, buf, flags, x, f):: Cint
201
211
catch exc
@@ -209,7 +219,9 @@ function _pyjl_get_buffer(o::C.PyPtr, buf::Ptr{C.Py_buffer}, flags::Cint)
209
219
end
210
220
211
221
function _pyjl_release_buffer (xo:: C.PyPtr , buf:: Ptr{C.Py_buffer} )
212
- delete! (PYJLBUFCACHE, UnsafePtr (buf). internal[! ])
222
+ Base. @lock PYJLBUFCACHE_LOCK begin
223
+ delete! (PYJLBUFCACHE, UnsafePtr (buf). internal[! ])
224
+ end
213
225
nothing
214
226
end
215
227
@@ -339,22 +351,31 @@ end
339
351
340
352
PyJuliaValue_IsNull (o) = Base. GC. @preserve o UnsafePtr {PyJuliaValueObject} (C. asptr (o)). value[] == 0
341
353
342
- PyJuliaValue_GetValue (o) = Base. GC. @preserve o PYJLVALUES[UnsafePtr {PyJuliaValueObject} (C. asptr (o)). value[]]
354
+ PyJuliaValue_GetValue (o) = Base. GC. @preserve o begin
355
+ idx = UnsafePtr {PyJuliaValueObject} (C. asptr (o)). value[]
356
+ Base. @lock PYJLVALUES_LOCK begin
357
+ PYJLVALUES[idx]
358
+ end
359
+ end
343
360
344
361
PyJuliaValue_SetValue (_o, @nospecialize (v)) = Base. GC. @preserve _o begin
345
362
o = C. asptr (_o)
346
363
idx = UnsafePtr {PyJuliaValueObject} (o). value[]
347
364
if idx == 0
348
- if isempty (PYJLFREEVALUES)
349
- push! (PYJLVALUES, v)
350
- idx = length (PYJLVALUES)
351
- else
352
- idx = pop! (PYJLFREEVALUES)
353
- PYJLVALUES[idx] = v
365
+ Base. @lock PYJLVALUES_LOCK begin
366
+ if isempty (PYJLFREEVALUES)
367
+ push! (PYJLVALUES, v)
368
+ idx = length (PYJLVALUES)
369
+ else
370
+ idx = pop! (PYJLFREEVALUES)
371
+ PYJLVALUES[idx] = v
372
+ end
354
373
end
355
374
UnsafePtr {PyJuliaValueObject} (o). value[] = idx
356
375
else
357
- PYJLVALUES[idx] = v
376
+ Base. @lock PYJLVALUES_LOCK begin
377
+ PYJLVALUES[idx] = v
378
+ end
358
379
end
359
380
nothing
360
381
end
0 commit comments