0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 04:42:18 +02:00

UI: Exit and show error if clearing scene data fails

This commit is contained in:
derrod 2023-05-03 14:59:48 +02:00 committed by Jim
parent 7ff5dd63b9
commit 4419786840
3 changed files with 56 additions and 5 deletions

View File

@ -502,6 +502,10 @@ MacPermissions.Continue="Continue"
UpdateAvailable="New Update Available"
UpdateAvailable.Text="Version %1.%2.%3 is now available. <a href='%4'>Click here to download</a>"
# Source leak error message
SourceLeak.Title="Source Cleanup Error"
SourceLeak.Text="There was a problem while changing scene collections and some sources could not be unloaded. This issue is typically caused by plugins that are not releasing resources properly. Please ensure that any plugins you are using are up to date.\n\nOBS Studio will now exit to prevent any potential data corruption."
# audio device names
Basic.DesktopDevice1="Desktop Audio"
Basic.DesktopDevice2="Desktop Audio 2"

View File

@ -1065,9 +1065,18 @@ static inline void AddMissingFiles(void *data, obs_source_t *source)
void OBSBasic::LoadData(obs_data_t *data, const char *file)
{
ClearSceneData();
InitDefaultTransitions();
ClearContextBar();
/* Exit OBS if clearing scene data failed for some reason. */
if (clearingFailed) {
OBSMessageBox::critical(this, QTStr("SourceLeak.Title"),
QTStr("SourceLeak.Text"));
close();
return;
}
InitDefaultTransitions();
if (devicePropertiesThread && devicePropertiesThread->isRunning()) {
devicePropertiesThread->wait();
devicePropertiesThread.reset();
@ -4880,10 +4889,45 @@ void OBSBasic::ClearSceneData()
unsetCursor();
disableSaving--;
/* If scene data wasn't actually cleared, e.g. faulty plugin holding a
* reference, they will still be in the hash table, enumerate them and
* store the names for logging purposes. */
auto cb2 = [](void *param, obs_source_t *source) {
auto orphans = static_cast<vector<string> *>(param);
orphans->push_back(obs_source_get_name(source));
return true;
};
blog(LOG_INFO, "All scene data cleared");
blog(LOG_INFO, "------------------------------------------------");
vector<string> orphan_sources;
obs_enum_sources(cb2, &orphan_sources);
if (!orphan_sources.empty()) {
/* Avoid logging list twice in case it gets called after
* setting the flag the first time. */
if (!clearingFailed) {
/* This ugly mess exists to join a vector of strings
* with a user-defined delimiter. */
string orphan_names = std::accumulate(
orphan_sources.begin(), orphan_sources.end(),
string(""), [](string a, string b) {
return std::move(a) + "\n- " + b;
});
blog(LOG_ERROR,
"Not all sources were cleared when clearing scene data:\n%s\n",
orphan_names.c_str());
}
/* We do not decrement disableSaving here to avoid OBS
* overwriting user data with garbage. */
clearingFailed = true;
} else {
disableSaving--;
blog(LOG_INFO, "All scene data cleared");
blog(LOG_INFO,
"------------------------------------------------");
}
}
void OBSBasic::closeEvent(QCloseEvent *event)
@ -4914,7 +4958,8 @@ void OBSBasic::closeEvent(QCloseEvent *event)
bool confirmOnExit =
config_get_bool(GetGlobalConfig(), "General", "ConfirmOnExit");
if (confirmOnExit && outputHandler && outputHandler->Active()) {
if (confirmOnExit && outputHandler && outputHandler->Active() &&
!clearingFailed) {
SetShowing(true);
QMessageBox::StandardButton button = OBSMessageBox::question(

View File

@ -245,6 +245,8 @@ private:
OBSWeakSourceAutoRelease copySourceTransition;
bool closing = false;
bool clearingFailed = false;
QScopedPointer<QThread> devicePropertiesThread;
QScopedPointer<QThread> whatsNewInitThread;
QScopedPointer<QThread> updateCheckThread;