Skip to content

Commit

Permalink
Create QApplication/QCoreApplication only once
Browse files Browse the repository at this point in the history
Fixes a crash that can occur due to QEvents being unexpectedly
deleted when an extra audqt::init() + cleanup() pair is called at
startup, as when the skins-qt plugin fails to load.
  • Loading branch information
jlindgren90 committed Jun 2, 2024
1 parent 4af143c commit ad71272
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 7 deletions.
3 changes: 3 additions & 0 deletions src/libaudcore/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ bool iface_plugin_set_current(PluginHandle * plugin);

void interface_run();

/* mainloop.cc */
void mainloop_cleanup();

/* playback.cc */
/* do not call these; use aud_drct_play/stop() instead */
void playback_play(int seek_time, bool pause);
Expand Down
21 changes: 17 additions & 4 deletions src/libaudcore/mainloop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ static bool cleanup_node(QueuedFuncNode * node)
delete node;
return true;
}

// inhibit all future callbacks at shutdown
static void enter_lockdown() { in_lockdown = true; }

Expand All @@ -374,10 +375,12 @@ EXPORT void mainloop_run()
static int dummy_argc = 1;
static char * dummy_argv[] = {app_name, nullptr};

if (qApp) // did audqt create a QApplication already?
qApp->exec();
else
QCoreApplication(dummy_argc, dummy_argv).exec();
// Create QCoreApplication instance if running in headless mode
// (otherwise audqt will have created a QApplication already).
if (!qApp)
new QCoreApplication(dummy_argc, dummy_argv);

qApp->exec();
}
else
#endif
Expand All @@ -402,3 +405,13 @@ EXPORT void mainloop_quit()
g_main_loop_quit(glib_mainloop);
}
}

void mainloop_cleanup()
{
#ifdef USE_QT
if (aud_get_mainloop_type() == MainloopType::Qt)
{
delete qApp;
}
#endif
}
4 changes: 4 additions & 0 deletions src/libaudcore/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,10 @@ EXPORT void aud_cleanup()
scanner_cleanup();
record_cleanup();

/* In Qt mode, this deletes the QApplication. This must be done
* after shutting down any GUI plugins but before unloading plugin
* modules (which will indirectly unload Qt shared libraries). */
mainloop_cleanup();
stop_plugins_one();

art_cleanup();
Expand Down
12 changes: 9 additions & 3 deletions src/libaudqt/audqt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ EXPORT void init()
return;

aud_config_set_defaults("audqt", audqt_defaults);
log_init();

// The QApplication instance is created only once and is not deleted
// by audqt::cleanup(). If it already exists, we are done here.
if (qApp)
return;

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && defined(_WIN32)
QApplication::setHighDpiScaleFactorRoundingPolicy(
Expand Down Expand Up @@ -178,8 +184,6 @@ EXPORT void init()
QApplication::setFont(QApplication::font("QSmallFont"), "QTreeView");
QApplication::setFont(QApplication::font("QTipLabel"), "QStatusBar");
#endif

log_init();
}

EXPORT void cleanup()
Expand All @@ -196,7 +200,9 @@ EXPORT void cleanup()

log_cleanup();

delete qApp;
// We do not delete the QApplication here due to issues that arise
// if it is deleted and then re-created. Instead, it is deleted
// later during shutdown; see mainloop_cleanup() in libaudcore.
}

EXPORT QGradientStops dark_bg_gradient(const QColor & base)
Expand Down

0 comments on commit ad71272

Please sign in to comment.