mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-15 02:37:51 -06:00
FIX: fix the crash issue #1944 caused by wronog thread name in some
corner cases this patch is cherry-picked from PrusaSlicer's 84722876012ca310e29b291e10fef9d18ae26cea thanks to 'Vojtech Bubnik' for the fix Implementing a test whether the current thread is the main (UI) thread and using it on AppConfig::save() to assert if save is called from a worker thread. The old assert was using thread names, which did not always work on Windows. Fixes #7839 #9178 #9370 #9420
This commit is contained in:
parent
12eec78d1d
commit
153c9517ce
4 changed files with 33 additions and 14 deletions
|
@ -393,6 +393,8 @@ int CLI::run(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Mark the main thread for the debugger and for runtime checks.
|
// Mark the main thread for the debugger and for runtime checks.
|
||||||
set_current_thread_name("bambustu_main");
|
set_current_thread_name("bambustu_main");
|
||||||
|
// Save the thread ID of the main thread.
|
||||||
|
save_main_thread_id();
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
// On Linux, wxGTK has no support for Wayland, and the app crashes on
|
// On Linux, wxGTK has no support for Wayland, and the app crashes on
|
||||||
|
|
|
@ -593,14 +593,8 @@ std::string AppConfig::load()
|
||||||
|
|
||||||
void AppConfig::save()
|
void AppConfig::save()
|
||||||
{
|
{
|
||||||
{
|
if (! is_main_thread_active())
|
||||||
// Returns "undefined" if the thread naming functionality is not supported by the operating system.
|
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
||||||
std::optional<std::string> current_thread_name = get_current_thread_name();
|
|
||||||
if (current_thread_name && *current_thread_name != "bambustu_main" && *current_thread_name != "main") {
|
|
||||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__<<", current_thread_name is " << *current_thread_name;
|
|
||||||
throw CriticalException("Calling AppConfig::save() from a worker thread, thread name: " + *current_thread_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The config is first written to a file with a PID suffix and then moved
|
// The config is first written to a file with a PID suffix and then moved
|
||||||
// to avoid race conditions with multiple instances of Slic3r
|
// to avoid race conditions with multiple instances of Slic3r
|
||||||
|
@ -872,12 +866,8 @@ std::string AppConfig::load()
|
||||||
|
|
||||||
void AppConfig::save()
|
void AppConfig::save()
|
||||||
{
|
{
|
||||||
{
|
if (! is_main_thread_active())
|
||||||
// Returns "undefined" if the thread naming functionality is not supported by the operating system.
|
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
||||||
std::optional<std::string> current_thread_name = get_current_thread_name();
|
|
||||||
if (current_thread_name && *current_thread_name != "bambustu_main")
|
|
||||||
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// The config is first written to a file with a PID suffix and then moved
|
// The config is first written to a file with a PID suffix and then moved
|
||||||
// to avoid race conditions with multiple instances of Slic3r
|
// to avoid race conditions with multiple instances of Slic3r
|
||||||
|
|
|
@ -187,6 +187,26 @@ std::optional<std::string> get_current_thread_name()
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// To be called at the start of the application to save the current thread ID as the main (UI) thread ID.
|
||||||
|
static boost::thread::id g_main_thread_id;
|
||||||
|
|
||||||
|
void save_main_thread_id()
|
||||||
|
{
|
||||||
|
g_main_thread_id = boost::this_thread::get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the cached main (UI) thread ID.
|
||||||
|
boost::thread::id get_main_thread_id()
|
||||||
|
{
|
||||||
|
return g_main_thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks whether the main (UI) thread is active.
|
||||||
|
bool is_main_thread_active()
|
||||||
|
{
|
||||||
|
return get_main_thread_id() == boost::this_thread::get_id();
|
||||||
|
}
|
||||||
|
|
||||||
// Spawn (n - 1) worker threads on Intel TBB thread pool and name them by an index and a system thread ID.
|
// Spawn (n - 1) worker threads on Intel TBB thread pool and name them by an index and a system thread ID.
|
||||||
// Also it sets locale of the worker threads to "C" for the G-code generator to produce "." as a decimal separator.
|
// Also it sets locale of the worker threads to "C" for the G-code generator to produce "." as a decimal separator.
|
||||||
void name_tbb_thread_pool_threads_set_locale()
|
void name_tbb_thread_pool_threads_set_locale()
|
||||||
|
|
|
@ -26,6 +26,13 @@ inline bool set_thread_name(boost::thread &thread, const std::string &thread_nam
|
||||||
bool set_current_thread_name(const char *thread_name);
|
bool set_current_thread_name(const char *thread_name);
|
||||||
inline bool set_current_thread_name(const std::string &thread_name) { return set_current_thread_name(thread_name.c_str()); }
|
inline bool set_current_thread_name(const std::string &thread_name) { return set_current_thread_name(thread_name.c_str()); }
|
||||||
|
|
||||||
|
// To be called at the start of the application to save the current thread ID as the main (UI) thread ID.
|
||||||
|
void save_main_thread_id();
|
||||||
|
// Retrieve the cached main (UI) thread ID.
|
||||||
|
boost::thread::id get_main_thread_id();
|
||||||
|
// Checks whether the main (UI) thread is active.
|
||||||
|
bool is_main_thread_active();
|
||||||
|
|
||||||
// Returns nullopt if not supported.
|
// Returns nullopt if not supported.
|
||||||
// Not supported by OSX.
|
// Not supported by OSX.
|
||||||
// Naming threads is only supported on newer Windows 10.
|
// Naming threads is only supported on newer Windows 10.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue