Skip to content

Commit ce8bd7a

Browse files
authoredJul 24, 2024··
simplify GIL handling (#530)
Co-authored-by: Christopher Doris <github.com/cjdoris>
1 parent 40fdbb9 commit ce8bd7a

File tree

11 files changed

+99
-144
lines changed

11 files changed

+99
-144
lines changed
 

‎pysrc/juliacall/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def args_from_config():
178178
os.environ['PATH'] = libdir
179179

180180
# Open the library
181-
CONFIG['lib'] = lib = c.CDLL(libpath, mode=c.RTLD_GLOBAL)
181+
CONFIG['lib'] = lib = c.PyDLL(libpath, mode=c.RTLD_GLOBAL)
182182

183183
# parse options
184184
argc, argv = args_from_config()

‎src/C/C.jl

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ include("consts.jl")
1717
include("pointers.jl")
1818
include("extras.jl")
1919
include("context.jl")
20-
include("gil.jl")
2120
include("api.jl")
2221

2322
function __init__()

‎src/C/context.jl

+57-63
Original file line numberDiff line numberDiff line change
@@ -145,63 +145,61 @@ function init_context()
145145
@require PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" init_pycall(PyCall)
146146

147147
# Initialize the interpreter
148-
with_gil() do
149-
CTX.is_preinitialized = Py_IsInitialized() != 0
150-
if CTX.is_preinitialized
151-
@assert CTX.which == :PyCall || CTX.matches_pycall isa Bool
148+
CTX.is_preinitialized = Py_IsInitialized() != 0
149+
if CTX.is_preinitialized
150+
@assert CTX.which == :PyCall || CTX.matches_pycall isa Bool
151+
else
152+
@assert CTX.which != :PyCall
153+
# Find ProgramName and PythonHome
154+
script = if Sys.iswindows()
155+
"""
156+
import sys
157+
print(sys.executable)
158+
if hasattr(sys, "base_exec_prefix"):
159+
sys.stdout.write(sys.base_exec_prefix)
160+
else:
161+
sys.stdout.write(sys.exec_prefix)
162+
"""
152163
else
153-
@assert CTX.which != :PyCall
154-
# Find ProgramName and PythonHome
155-
script = if Sys.iswindows()
156-
"""
157-
import sys
158-
print(sys.executable)
159-
if hasattr(sys, "base_exec_prefix"):
160-
sys.stdout.write(sys.base_exec_prefix)
161-
else:
162-
sys.stdout.write(sys.exec_prefix)
163-
"""
164-
else
165-
"""
166-
import sys
167-
print(sys.executable)
168-
if hasattr(sys, "base_exec_prefix"):
169-
sys.stdout.write(sys.base_prefix)
170-
sys.stdout.write(":")
171-
sys.stdout.write(sys.base_exec_prefix)
172-
else:
173-
sys.stdout.write(sys.prefix)
174-
sys.stdout.write(":")
175-
sys.stdout.write(sys.exec_prefix)
176-
"""
177-
end
178-
CTX.pyprogname, CTX.pyhome = readlines(python_cmd(["-c", script]))
164+
"""
165+
import sys
166+
print(sys.executable)
167+
if hasattr(sys, "base_exec_prefix"):
168+
sys.stdout.write(sys.base_prefix)
169+
sys.stdout.write(":")
170+
sys.stdout.write(sys.base_exec_prefix)
171+
else:
172+
sys.stdout.write(sys.prefix)
173+
sys.stdout.write(":")
174+
sys.stdout.write(sys.exec_prefix)
175+
"""
176+
end
177+
CTX.pyprogname, CTX.pyhome = readlines(python_cmd(["-c", script]))
179178

180-
# Set PythonHome
181-
CTX.pyhome_w = Base.cconvert(Cwstring, CTX.pyhome)
182-
Py_SetPythonHome(pointer(CTX.pyhome_w))
179+
# Set PythonHome
180+
CTX.pyhome_w = Base.cconvert(Cwstring, CTX.pyhome)
181+
Py_SetPythonHome(pointer(CTX.pyhome_w))
183182

184-
# Set ProgramName
185-
CTX.pyprogname_w = Base.cconvert(Cwstring, CTX.pyprogname)
186-
Py_SetProgramName(pointer(CTX.pyprogname_w))
183+
# Set ProgramName
184+
CTX.pyprogname_w = Base.cconvert(Cwstring, CTX.pyprogname)
185+
Py_SetProgramName(pointer(CTX.pyprogname_w))
187186

188-
# Start the interpreter and register exit hooks
189-
Py_InitializeEx(0)
190-
atexit() do
191-
CTX.is_initialized = false
192-
if CTX.version === missing || CTX.version < v"3.6"
193-
Py_Finalize()
194-
else
195-
if Py_FinalizeEx() == -1
196-
@warn "Py_FinalizeEx() error"
197-
end
187+
# Start the interpreter and register exit hooks
188+
Py_InitializeEx(0)
189+
atexit() do
190+
CTX.is_initialized = false
191+
if CTX.version === missing || CTX.version < v"3.6"
192+
Py_Finalize()
193+
else
194+
if Py_FinalizeEx() == -1
195+
@warn "Py_FinalizeEx() error"
198196
end
199197
end
200198
end
201-
CTX.is_initialized = true
202-
if Py_AtExit(@cfunction(_atpyexit, Cvoid, ())) == -1
203-
@warn "Py_AtExit() error"
204-
end
199+
end
200+
CTX.is_initialized = true
201+
if Py_AtExit(@cfunction(_atpyexit, Cvoid, ())) == -1
202+
@warn "Py_AtExit() error"
205203
end
206204
end
207205

@@ -218,20 +216,16 @@ function init_context()
218216
ENV["JULIA_PYTHONCALL_EXE"] = CTX.exe_path::String
219217
end
220218

221-
with_gil() do
222-
223-
# Get the python version
224-
verstr = Base.unsafe_string(Py_GetVersion())
225-
vermatch = match(r"^[0-9.]+", verstr)
226-
if vermatch === nothing
227-
error("Cannot parse version from version string: $(repr(verstr))")
228-
end
229-
CTX.version = VersionNumber(vermatch.match)
230-
v"3.5" CTX.version < v"4" || error(
231-
"Only Python 3.5+ is supported, this is Python $(CTX.version) at $(CTX.exe_path===missing ? "unknown location" : CTX.exe_path).",
232-
)
233-
219+
# Get the python version
220+
verstr = Base.unsafe_string(Py_GetVersion())
221+
vermatch = match(r"^[0-9.]+", verstr)
222+
if vermatch === nothing
223+
error("Cannot parse version from version string: $(repr(verstr))")
234224
end
225+
CTX.version = VersionNumber(vermatch.match)
226+
v"3.5" CTX.version < v"4" || error(
227+
"Only Python 3.5+ is supported, this is Python $(CTX.version) at $(CTX.exe_path===missing ? "unknown location" : CTX.exe_path).",
228+
)
235229

236230
@debug "Initialized PythonCall.jl" CTX.is_embedded CTX.is_initialized CTX.exe_path CTX.lib_path CTX.lib_ptr CTX.pyprogname CTX.pyhome CTX.version
237231

‎src/C/gil.jl

-24
This file was deleted.

‎src/C/pointers.jl

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const CAPI_FUNC_SIGS = Dict{Symbol,Pair{Tuple,Type}}(
2222
:PyEval_RestoreThread => (Ptr{Cvoid},) => Cvoid,
2323
:PyGILState_Ensure => () => PyGILState_STATE,
2424
:PyGILState_Release => (PyGILState_STATE,) => Cvoid,
25+
:PyGILState_GetThisThreadState => () => Ptr{Cvoid},
26+
:PyGILState_Check => () => Cint,
2527
# IMPORT
2628
:PyImport_ImportModule => (Ptr{Cchar},) => PyPtr,
2729
:PyImport_Import => (PyPtr,) => PyPtr,

‎src/Compat/Compat.jl

+3-5
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@ include("tables.jl")
3434
include("pycall.jl")
3535

3636
function __init__()
37-
C.with_gil() do
38-
init_gui()
39-
init_pyshow()
40-
init_tables()
41-
end
37+
init_gui()
38+
init_pyshow()
39+
init_tables()
4240
@require PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" init_pycall(PyCall)
4341
end
4442
end

‎src/Convert/Convert.jl

+4-6
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,10 @@ include("numpy.jl")
5555
include("pandas.jl")
5656

5757
function __init__()
58-
C.with_gil() do
59-
init_pyconvert()
60-
init_ctypes()
61-
init_numpy()
62-
init_pandas()
63-
end
58+
init_pyconvert()
59+
init_ctypes()
60+
init_numpy()
61+
init_pandas()
6462
end
6563

6664
end

‎src/Core/Core.jl

+4-6
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,10 @@ include("juliacall.jl")
3939
include("pyconst_macro.jl")
4040

4141
function __init__()
42-
C.with_gil() do
43-
init_consts()
44-
init_datetime()
45-
init_stdlib()
46-
init_juliacall()
47-
end
42+
init_consts()
43+
init_datetime()
44+
init_stdlib()
45+
init_juliacall()
4846
end
4947

5048
end

‎src/GC/GC.jl

+7-13
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,9 @@ Like most PythonCall functions, you must only call this from the main thread.
4040
function enable()
4141
ENABLED[] = true
4242
if !isempty(QUEUE)
43-
C.with_gil(false) do
44-
for ptr in QUEUE
45-
if ptr != C.PyNULL
46-
C.Py_DecRef(ptr)
47-
end
43+
for ptr in QUEUE
44+
if ptr != C.PyNULL
45+
C.Py_DecRef(ptr)
4846
end
4947
end
5048
end
@@ -55,9 +53,7 @@ end
5553
function enqueue(ptr::C.PyPtr)
5654
if ptr != C.PyNULL && C.CTX.is_initialized
5755
if ENABLED[]
58-
C.with_gil(false) do
59-
C.Py_DecRef(ptr)
60-
end
56+
C.Py_DecRef(ptr)
6157
else
6258
push!(QUEUE, ptr)
6359
end
@@ -68,11 +64,9 @@ end
6864
function enqueue_all(ptrs)
6965
if C.CTX.is_initialized
7066
if ENABLED[]
71-
C.with_gil(false) do
72-
for ptr in ptrs
73-
if ptr != C.PyNULL
74-
C.Py_DecRef(ptr)
75-
end
67+
for ptr in ptrs
68+
if ptr != C.PyNULL
69+
C.Py_DecRef(ptr)
7670
end
7771
end
7872
else

‎src/JlWrap/C.jl

+1-3
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,7 @@ function init_c()
334334
end
335335

336336
function __init__()
337-
C.with_gil() do
338-
init_c()
339-
end
337+
init_c()
340338
end
341339

342340
PyJuliaValue_IsNull(o::C.PyPtr) = UnsafePtr{PyJuliaValueObject}(o).value[] == 0

‎src/JlWrap/JlWrap.jl

+20-22
Original file line numberDiff line numberDiff line change
@@ -65,28 +65,26 @@ include("set.jl")
6565
include("callback.jl")
6666

6767
function __init__()
68-
Cjl.C.with_gil() do
69-
init_base()
70-
init_raw()
71-
init_any()
72-
init_iter()
73-
init_type()
74-
init_module()
75-
init_io()
76-
init_number()
77-
init_array()
78-
init_vector()
79-
init_dict()
80-
init_set()
81-
init_callback()
82-
# add packages to juliacall
83-
jl = pyjuliacallmodule
84-
jl.Core = Base.Core
85-
jl.Base = Base
86-
jl.Main = Main
87-
jl.Pkg = Pkg
88-
jl.PythonCall = PythonCall
89-
end
68+
init_base()
69+
init_raw()
70+
init_any()
71+
init_iter()
72+
init_type()
73+
init_module()
74+
init_io()
75+
init_number()
76+
init_array()
77+
init_vector()
78+
init_dict()
79+
init_set()
80+
init_callback()
81+
# add packages to juliacall
82+
jl = pyjuliacallmodule
83+
jl.Core = Base.Core
84+
jl.Base = Base
85+
jl.Main = Main
86+
jl.Pkg = Pkg
87+
jl.PythonCall = PythonCall
9088
end
9189

9290
end

0 commit comments

Comments
 (0)
Please sign in to comment.