Skip to content

Commit 46ef437

Browse files
author
Christopher Doris
committed
adds gc_disable/gc_enable to allow delaying GC of python objects
1 parent 0c9bac7 commit 46ef437

File tree

4 files changed

+55
-16
lines changed

4 files changed

+55
-16
lines changed

src/Py.jl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,7 @@ mutable struct Py
4343
end
4444
export Py
4545

46-
function py_finalizer(x::Py)
47-
if C.CTX.is_initialized
48-
C.with_gil(false) do
49-
C.Py_DecRef(getptr(x))
50-
end
51-
end
52-
end
46+
py_finalizer(x::Py) = C.gc_enqueue(getptr(x))
5347

5448
ispy(::Py) = true
5549
getptr(x::Py) = getfield(x, :ptr)

src/cpython/CPython.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ include("extras.jl")
1616
include("context.jl")
1717
include("gil.jl")
1818
include("jlwrap.jl")
19+
include("gc.jl")
1920

2021
function __init__()
2122
init_context()

src/cpython/gc.jl

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const GC_ENABLED = Ref(true)
2+
const GC_QUEUE = PyPtr[]
3+
4+
function gc_disable()
5+
GC_ENABLED[] = false
6+
return
7+
end
8+
9+
function gc_enable()
10+
GC_ENABLED[] = true
11+
if !isempty(GC_QUEUE)
12+
with_gil(false) do
13+
for ptr in GC_QUEUE
14+
if ptr != PyNULL
15+
Py_DecRef(ptr)
16+
end
17+
end
18+
end
19+
end
20+
empty!(GC_QUEUE)
21+
return
22+
end
23+
24+
function gc_enqueue(ptr::PyPtr)
25+
if ptr != PyNULL && CTX.is_initialized
26+
if GC_ENABLED[]
27+
with_gil(false) do
28+
Py_DecRef(ptr)
29+
end
30+
else
31+
push!(GC_QUEUE, ptr)
32+
end
33+
end
34+
return
35+
end
36+
37+
function gc_enqueue_all(ptrs)
38+
if CTX.is_initialized
39+
if GC_ENABLED[]
40+
with_gil(false) do
41+
for ptr in ptrs
42+
if ptr != PyNULL
43+
Py_DecRef(ptr)
44+
end
45+
end
46+
end
47+
else
48+
append!(GC_QUEUE, ptrs)
49+
end
50+
end
51+
return
52+
end

src/jlwrap/objectarray.jl

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,7 @@ PyObjectArray(undef::UndefInitializer, dims::Vararg{Integer,N}) where {N} = PyOb
2323
PyObjectArray{N}(x::AbstractArray{T,N}) where {T,N} = copyto!(PyObjectArray{N}(undef, size(x)), x)
2424
PyObjectArray(x::AbstractArray{T,N}) where {T,N} = PyObjectArray{N}(x)
2525

26-
pyobjectarray_finalizer(x::PyObjectArray) = begin
27-
if C.CTX.is_initialized
28-
C.with_gil(false) do
29-
for ptr in x.ptrs
30-
C.Py_DecRef(ptr)
31-
end
32-
end
33-
end
34-
end
26+
pyobjectarray_finalizer(x::PyObjectArray) = C.gc_enqueue_all(x.ptrs)
3527

3628
Base.IndexStyle(x) = Base.IndexStyle(x.ptrs)
3729

0 commit comments

Comments
 (0)