diff --git a/src/PyCall.jl b/src/PyCall.jl index f1987a29..c7e4e0b1 100644 --- a/src/PyCall.jl +++ b/src/PyCall.jl @@ -76,11 +76,22 @@ mutable struct PyObject o::PyPtr # the actual PyObject* function PyObject(o::PyPtr) po = new(o) - finalizer(pydecref, po) - return po + finalizer(_pydecref_eventually, po) end end +# we can only call pydecref from the main thread. if we happen to hit +# GC from a different thread, add the finalizer back to the finalization +# queue to try again later when we'll eventually be on the main thread. +function _pydecref_eventually(po) + if Threads.threadid()==1 + pydecref(po) + else + finalizer(_pydecref_eventually, po) + end + return nothing +end + PyPtr(o::PyObject) = getfield(o, :o) """ diff --git a/src/pybuffer.jl b/src/pybuffer.jl index a2cec72d..cdabca14 100644 --- a/src/pybuffer.jl +++ b/src/pybuffer.jl @@ -32,7 +32,7 @@ mutable struct PyBuffer b = new(Py_buffer(C_NULL, PyPtr_NULL, 0, 0, 0, 0, C_NULL, C_NULL, C_NULL, C_NULL, C_NULL, C_NULL, C_NULL)) - finalizer(pydecref, b) + finalizer(_pydecref_eventually, b) return b end end