2150{
2151 ScriptCompletion completion;
2152
2153 {
2155 if (!lease) {
2156 completion.error =
_u8L(
"Python interpreter is shutting down.");
2157 } else {
2158 pybind11::gil_scoped_acquire gil;
2159
2160 if (
run->cancel_requested.load(std::memory_order_acquire)) {
2161
2162 completion.cancelled = true;
2163 } else {
2164
2165
2166 PluginCapabilityInterface::RefCounter ref_counter(*
run->capability);
2167
2168 std::optional<ScopedPluginAuditContext> audit_scope;
2169 if (!
run->capability->audit_plugin_key().empty())
2170 audit_scope.emplace(
run->capability->audit_plugin_key(),
run->capability->name());
2171
2172
2173
2175 if (!invocation.error.empty()) {
2176 completion.error = invocation.error;
2177 } else if (!invocation.is_async) {
2178 completion.result = invocation.result;
2179 }
else if (
run->cancel_requested.load(std::memory_order_acquire)) {
2180 completion.cancelled = true;
2181 } else {
2182 try {
2183 pybind11::module_ asyncio = pybind11::module_::import("asyncio");
2184 pybind11::object loop = asyncio.attr("new_event_loop")();
2185 asyncio.attr("set_event_loop")(loop);
2186
2188 Py_INCREF(tl_script_loop);
2189
2190 pybind11::object task = loop.attr("create_task")(std::move(invocation.awaitable));
2191 {
2192 std::lock_guard<std::mutex>
lock(
run->handle_mutex);
2195 }
2196 run->has_loop.store(
true, std::memory_order_release);
2197
2198 if (
run->cancel_requested.load(std::memory_order_acquire))
2199 loop.attr("call_soon_threadsafe")(task.attr("cancel"));
2200
2201 try {
2202 pybind11::object returned = loop.attr("run_until_complete")(task);
2203 completion.result = returned.cast<ExecutionResult>();
2204 } catch (pybind11::error_already_set& err) {
2205
2206
2207 if (err.matches(asyncio.attr("CancelledError")) &&
2208 run->cancel_requested.load(std::memory_order_acquire)) {
2209 completion.cancelled = true;
2210 } else {
2212 completion.error = err.what();
2213 }
2214 }
2215
2216 run->has_loop.store(
false, std::memory_order_release);
2217 {
2218 std::lock_guard<std::mutex>
lock(
run->handle_mutex);
2219 run->task = pybind11::object();
2220 run->loop = pybind11::object();
2221 }
2222 Py_CLEAR(tl_script_loop);
2223 loop.attr("close")();
2224 asyncio.attr("set_event_loop")(pybind11::none());
2225 } catch (pybind11::error_already_set& err) {
2227 completion.error = err.what();
2228 } catch (const std::exception& ex) {
2229 completion.error = ex.what();
2230 }
2231
2232
2233 if (
run->has_loop.load(std::memory_order_acquire)) {
2234 run->has_loop.store(
false, std::memory_order_release);
2235 std::lock_guard<std::mutex>
lock(
run->handle_mutex);
2236 run->task = pybind11::object();
2237 run->loop = pybind11::object();
2238 }
2239
2240 if (tl_script_loop != nullptr)
2241 Py_CLEAR(tl_script_loop);
2242 }
2243 }
2244
2245
2246
2247
2248 run->capability.reset();
2249 }
2250 }
2251
2252
2253
2254
2255 if (
run->cancel_requested.load(std::memory_order_acquire)) {
2256 completion.cancelled = true;
2257 completion.error.clear();
2258 }
2259
2260 auto on_done = std::move(
run->on_done);
2261 auto deliver = [on_done, completion]() {
2262 if (on_done)
2263 on_done(completion);
2264 };
2265
2266 if (wxTheApp == nullptr || wxIsMainThread())
2267 deliver();
2268 else
2269 GUI::wxGetApp().CallAfter(deliver);
2270
2271
2272
2273 {
2274 std::lock_guard<std::mutex>
lock(
mutex);
2276 }
2278}
PythonRuntimeLease acquire_runtime_lease()
Definition PythonInterpreter.hpp:162
static PythonInterpreter & instance()
Definition PythonInterpreter.cpp:434
AppActionRunResult run(const std::string &key, const std::string ¶m={})
Definition NativeCommands.cpp:668
PyObject * tl_script_loop
Definition PluginManager.cpp:2116
ScriptExecuteInvocation invoke_script_execute(const std::shared_ptr< PluginCapabilityInterface > &capability)
Definition PyPluginTrampoline.hpp:101
void log_python_exception_keep(pybind11::error_already_set &err)
Definition PythonInterpreter.cpp:96
@ lock
Definition GLGizmoEmboss.cpp:209
#define _u8L(s)
Definition I18N.hpp:11
std::vector< std::shared_ptr< Run > > active
Definition PluginManager.cpp:2142
std::condition_variable cv
Definition PluginManager.cpp:2141
std::mutex mutex
Definition PluginManager.cpp:2140