OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::ScriptAsyncRuntime Class Reference
module nullptr

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/plugin/PluginManager.hpp>

Collaboration diagram for Slic3r::ScriptAsyncRuntime:

Classes

struct  Impl

Public Member Functions

 ~ScriptAsyncRuntime ()
 ScriptAsyncRuntime (const ScriptAsyncRuntime &)=delete
ScriptAsyncRuntime & operator= (const ScriptAsyncRuntime &)=delete
bool start (const std::string &plugin_key, const std::string &capability_name, std::shared_ptr< PluginCapabilityInterface > capability, std::function< void(const ScriptCompletion &)> on_done)
void cancel_plugin (const std::string &plugin_key)
bool has_active_run (const PluginCapabilityInterface *capability) const
void shutdown ()
void reset ()

Static Public Member Functions

static ScriptAsyncRuntime & instance ()
static pybind11::object current_loop ()

Private Member Functions

 ScriptAsyncRuntime ()

Private Attributes

std::unique_ptr< Impl > m_impl

Detailed Description

Constructor & Destructor Documentation

◆ ~ScriptAsyncRuntime()

Slic3r::ScriptAsyncRuntime::~ScriptAsyncRuntime ( )
2288{ shutdown(); }
void shutdown()
Definition PluginManager.cpp:2376

References shutdown().

Here is the call graph for this function:

◆ ScriptAsyncRuntime() [1/2]

Slic3r::ScriptAsyncRuntime::ScriptAsyncRuntime ( const ScriptAsyncRuntime & )
delete

References ScriptAsyncRuntime().

Referenced by ScriptAsyncRuntime(), instance(), and operator=().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ScriptAsyncRuntime() [2/2]

Slic3r::ScriptAsyncRuntime::ScriptAsyncRuntime ( )
private
2286: m_impl(std::make_unique<Impl>()) {}
std::unique_ptr< Impl > m_impl
Definition PluginManager.hpp:411

References m_impl, and Slic3r::make_unique().

Here is the call graph for this function:

Member Function Documentation

◆ cancel_plugin()

void Slic3r::ScriptAsyncRuntime::cancel_plugin ( const std::string & plugin_key)
2327{
2328 std::vector<std::shared_ptr<Impl::Run>> runs;
2329 {
2330 std::lock_guard<std::mutex> lock(m_impl->mutex);
2331 for (const auto& run : m_impl->active)
2332 if (run->plugin_key == plugin_key)
2333 runs.push_back(run);
2334 }
2335
2336 for (const auto& run : runs)
2337 run->cancel_requested.store(true, std::memory_order_release);
2338
2339 for (const auto& run : runs) {
2340 // A synchronous invocation has no loop to cancel; skip it so the caller never blocks on
2341 // the GIL while that invocation is (uninterruptibly) running.
2342 if (!run->has_loop.load(std::memory_order_acquire))
2343 continue;
2344
2345 PythonGILState gil;
2346 if (!gil)
2347 continue;
2348
2349 pybind11::object loop;
2350 pybind11::object task;
2351 {
2352 std::lock_guard<std::mutex> lock(run->handle_mutex);
2353 loop = run->loop;
2354 task = run->task;
2355 }
2356 if (!loop || !task)
2357 continue;
2358
2359 try {
2360 loop.attr("call_soon_threadsafe")(task.attr("cancel"));
2361 } catch (const std::exception& ex) {
2362 BOOST_LOG_TRIVIAL(warning) << "Script async cancel failed for plugin '" << plugin_key << "': " << ex.what();
2363 }
2364 }
2365}
AppActionRunResult run(const std::string &key, const std::string &param={})
Definition NativeCommands.cpp:668
@ lock
Definition GLGizmoEmboss.cpp:209

References m_impl.

Referenced by Slic3r::PluginManager::cancel_and_wait_for_capabilities().

Here is the caller graph for this function:

◆ current_loop()

pybind11::object Slic3r::ScriptAsyncRuntime::current_loop ( )
static
2396{
2397 if (tl_script_loop == nullptr)
2398 return pybind11::object();
2399 return pybind11::reinterpret_borrow<pybind11::object>(pybind11::handle(tl_script_loop));
2400}

◆ has_active_run()

bool Slic3r::ScriptAsyncRuntime::has_active_run ( const PluginCapabilityInterface * capability) const
2368{
2369 std::lock_guard<std::mutex> lock(m_impl->mutex);
2370 for (const auto& run : m_impl->active)
2371 if (run->capability.get() == capability)
2372 return true;
2373 return false;
2374}

References m_impl.

◆ instance()

ScriptAsyncRuntime & Slic3r::ScriptAsyncRuntime::instance ( )
static
2281{
2282 static ScriptAsyncRuntime inst;
2283 return inst;
2284}
ScriptAsyncRuntime(const ScriptAsyncRuntime &)=delete

References ScriptAsyncRuntime().

Referenced by Slic3r::PluginManager::cancel_and_wait_for_capabilities(), Slic3r::PluginManager::initialize(), Slic3r::PluginManager::instance(), Slic3r::PluginManager::launch_script_capability(), and Slic3r::PluginManager::shutdown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=()

ScriptAsyncRuntime & Slic3r::ScriptAsyncRuntime::operator= ( const ScriptAsyncRuntime & )
delete

References ScriptAsyncRuntime().

Here is the call graph for this function:

◆ reset()

void Slic3r::ScriptAsyncRuntime::reset ( )
2388{
2389 shutdown();
2390
2391 std::lock_guard<std::mutex> lock(m_impl->mutex);
2392 m_impl->stopping = false;
2393}

References m_impl, and shutdown().

Referenced by Slic3r::PluginManager::initialize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown()

void Slic3r::ScriptAsyncRuntime::shutdown ( )
2377{
2378 {
2379 std::lock_guard<std::mutex> lock(m_impl->mutex);
2380 m_impl->stopping = true;
2381 }
2382
2383 std::unique_lock<std::mutex> lock(m_impl->mutex);
2384 m_impl->cv.wait(lock, [this] { return m_impl->active.empty(); });
2385}

References m_impl.

Referenced by ~ScriptAsyncRuntime(), reset(), and Slic3r::PluginManager::shutdown().

Here is the caller graph for this function:

◆ start()

bool Slic3r::ScriptAsyncRuntime::start ( const std::string & plugin_key,
const std::string & capability_name,
std::shared_ptr< PluginCapabilityInterface > capability,
std::function< void(const ScriptCompletion &)> on_done )
2294{
2295 if (!PythonInterpreter::instance().is_initialized())
2296 return false;
2297
2298 auto run = std::make_shared<Impl::Run>();
2299 run->plugin_key = plugin_key;
2300 run->capability_name = capability_name;
2301 run->capability = std::move(capability);
2302 run->on_done = std::move(on_done);
2303
2304 {
2305 std::lock_guard<std::mutex> lock(m_impl->mutex);
2306 if (m_impl->stopping)
2307 return false;
2308 m_impl->active.push_back(run);
2309 }
2310
2311 // One worker thread per invocation. A stalled invocation of one plugin can never delay another
2312 // plugin's unload or another invocation, and no invocation body ever runs on the caller (UI)
2313 // thread. The thread holds `run` (and so the capability) until it finishes; the runtime tracks
2314 // it in `active` and waits for it on shutdown.
2315 Impl* impl = m_impl.get();
2316 try {
2317 std::thread([impl, run] { impl->run_invocation(run); }).detach();
2318 } catch (...) {
2319 std::lock_guard<std::mutex> lock(m_impl->mutex);
2320 m_impl->active.erase(std::remove(m_impl->active.begin(), m_impl->active.end(), run), m_impl->active.end());
2321 return false;
2322 }
2323 return true;
2324}
static PythonInterpreter & instance()
Definition PythonInterpreter.cpp:434
Definition PluginManager.cpp:2121

References Slic3r::PythonInterpreter::instance(), and m_impl.

Referenced by Slic3r::PluginManager::launch_script_capability().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_impl

std::unique_ptr<Impl> Slic3r::ScriptAsyncRuntime::m_impl
private

The documentation for this class was generated from the following files: