Skip to content

Commit 129fda4

Browse files
committed
fix: safer PYJLVALUES
1 parent 2eca398 commit 129fda4

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

src/JlWrap/C.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ const PyJuliaBase_Type = Ref(C.PyNULL)
1616

1717
# we store the actual julia values here
1818
# the `value` field of `PyJuliaValueObject` indexes into here
19-
const PYJLVALUES = []
19+
const PYJLVALUES = IdDict{Int,Any}()
2020
# unused indices in PYJLVALUES
2121
const PYJLFREEVALUES = Int[]
2222
# Thread safety for PYJLVALUES and PYJLFREEVALUES
2323
const PYJLVALUES_LOCK = Threads.SpinLock()
24+
# Track next available index
25+
const PYJLVALUES_NEXT_IDX = Ref(1)
2426

2527
function _pyjl_new(t::C.PyPtr, ::C.PyPtr, ::C.PyPtr)
2628
o = ccall(UnsafePtr{C.PyTypeObject}(t).alloc[!], C.PyPtr, (C.PyPtr, C.Py_ssize_t), t, 0)
@@ -34,7 +36,7 @@ function _pyjl_dealloc(o::C.PyPtr)
3436
idx = UnsafePtr{PyJuliaValueObject}(o).value[]
3537
if idx != 0
3638
Base.@lock PYJLVALUES_LOCK begin
37-
PYJLVALUES[idx] = nothing
39+
delete!(PYJLVALUES, idx)
3840
push!(PYJLFREEVALUES, idx)
3941
end
4042
end
@@ -364,12 +366,12 @@ PyJuliaValue_SetValue(_o, @nospecialize(v)) = Base.GC.@preserve _o begin
364366
if idx == 0
365367
Base.@lock PYJLVALUES_LOCK begin
366368
if isempty(PYJLFREEVALUES)
367-
push!(PYJLVALUES, v)
368-
idx = length(PYJLVALUES)
369+
idx = PYJLVALUES_NEXT_IDX[]
370+
PYJLVALUES_NEXT_IDX[] += 1
369371
else
370372
idx = pop!(PYJLFREEVALUES)
371-
PYJLVALUES[idx] = v
372373
end
374+
PYJLVALUES[idx] = v
373375
end
374376
UnsafePtr{PyJuliaValueObject}(o).value[] = idx
375377
else

0 commit comments

Comments
 (0)