From 60decefab2940c754de24c578e3e461845422f6d Mon Sep 17 00:00:00 2001 From: uentity Date: Tue, 6 Nov 2018 09:15:45 +0500 Subject: [PATCH] Fix async Python functors invoking from multiple C++ threads (#1587) Ensure GIL is held during functor destruction. --- include/pybind11/functional.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/include/pybind11/functional.h b/include/pybind11/functional.h index 9cdf21f7ad9..f15d3dc468e 100644 --- a/include/pybind11/functional.h +++ b/include/pybind11/functional.h @@ -54,9 +54,20 @@ struct type_caster> { } } - value = [func](Args... args) -> Return { + // ensure GIL is held during functor destruction + struct func_handle { + function f; + func_handle(function&& f_) : f(std::move(f_)) {} + func_handle(const func_handle&) = default; + ~func_handle() { + gil_scoped_acquire acq; + f.release().dec_ref(); + } + }; + + value = [hfunc = func_handle(std::move(func))](Args... args) -> Return { gil_scoped_acquire acq; - object retval(func(std::forward(args)...)); + object retval(hfunc.f(std::forward(args)...)); /* Visual studio 2015 parser issue: need parentheses around this expression */ return (retval.template cast()); };