-
Notifications
You must be signed in to change notification settings - Fork 66
/
GC.jl
85 lines (70 loc) · 1.76 KB
/
GC.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""
module PythonCall.GC
Garbage collection of Python objects.
See `disable` and `enable`.
"""
module GC
using ..C: C
const ENABLED = Ref(true)
const QUEUE = C.PyPtr[]
"""
PythonCall.GC.disable()
Disable the PythonCall garbage collector.
This means that whenever a Python object owned by Julia is finalized, it is not immediately
freed but is instead added to a queue of objects to free later when `enable()` is called.
Like most PythonCall functions, you must only call this from the main thread.
"""
function disable()
ENABLED[] = false
return
end
"""
PythonCall.GC.enable()
Re-enable the PythonCall garbage collector.
This frees any Python objects which were finalized while the GC was disabled, and allows
objects finalized in the future to be freed immediately.
Like most PythonCall functions, you must only call this from the main thread.
"""
function enable()
ENABLED[] = true
if !isempty(QUEUE)
C.with_gil(false) do
for ptr in QUEUE
if ptr != C.PyNULL
C.Py_DecRef(ptr)
end
end
end
end
empty!(QUEUE)
return
end
function enqueue(ptr::C.PyPtr)
if ptr != C.PyNULL && C.CTX.is_initialized
if ENABLED[]
C.with_gil(false) do
C.Py_DecRef(ptr)
end
else
push!(QUEUE, ptr)
end
end
return
end
function enqueue_all(ptrs)
if C.CTX.is_initialized
if ENABLED[]
C.with_gil(false) do
for ptr in ptrs
if ptr != C.PyNULL
C.Py_DecRef(ptr)
end
end
end
else
append!(QUEUE, ptrs)
end
end
return
end
end # module GC