mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-06-30 07:15:32 +02:00
[game_list] fix crash and flashing from the directory watcher (#4099)
So the game list watcher could rebuild the content providers (CreateFactories) while the populate worker was still scanning them, and the worker would walk a torn-down RegisteredCache and segfault in OpenFileOrDirectoryConcat. Fixed by stopping and joining the worker before rebuilding. On macOS the watcher also re-armed itself every populate. Re-adding the same paths makes QFileSystemWatcher re-emit directoryChanged (the FSEvent comes in async, so the blockSignals guard misses it), so it just kept refreshing and the list flashed forever. Now it only re-arms when the watched dirs actually changed. Also null-guarded OpenFileOrDirectoryConcat so a torn-down cache cant null-deref there. Related: https://github.com/eden-emulator/Issue-Reports/issues/336 Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4099 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: MaranBr <maranbr@eden-emu.dev>
This commit is contained in:
parent
c27266c4cd
commit
ce14fc91fb
4 changed files with 50 additions and 16 deletions
|
|
@ -57,6 +57,12 @@ void GameListModel::PopulateAsync(QVector<UISettings::GameDir>& game_dirs) {
|
|||
QThreadPool::globalInstance()->start(current_worker.get());
|
||||
}
|
||||
|
||||
void GameListModel::StopWorker() {
|
||||
// ~GameListWorker sets stop_requested and blocks until run() finishes, so this returns only
|
||||
// once the worker is no longer touching the content providers.
|
||||
current_worker.reset();
|
||||
}
|
||||
|
||||
void GameListModel::WorkerEvent() {
|
||||
current_worker->ProcessEvents(this);
|
||||
}
|
||||
|
|
@ -202,6 +208,7 @@ void GameListModel::RefreshGameDirectory() {
|
|||
|
||||
if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) {
|
||||
LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
|
||||
StopWorker();
|
||||
QtCommon::system->GetFileSystemController().CreateFactories(*QtCommon::vfs);
|
||||
PopulateAsync(UISettings::values.game_dirs);
|
||||
}
|
||||
|
|
@ -210,6 +217,7 @@ void GameListModel::RefreshGameDirectory() {
|
|||
void GameListModel::RefreshExternalContent() {
|
||||
if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) {
|
||||
LOG_INFO(Frontend, "External content directory changed. Clearing metadata cache.");
|
||||
StopWorker();
|
||||
QtCommon::Game::ResetMetadata(false);
|
||||
QtCommon::system->GetFileSystemController().CreateFactories(*QtCommon::vfs);
|
||||
PopulateAsync(UISettings::values.game_dirs);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ public:
|
|||
void DonePopulating(const QStringList& watch_list);
|
||||
|
||||
void PopulateAsync(QVector<UISettings::GameDir>& game_dirs);
|
||||
// Stops and joins the running populate worker, if any. Must be called before rebuilding the
|
||||
// content providers (CreateFactories), otherwise the worker keeps scanning a cache that is
|
||||
// being torn down underneath it.
|
||||
void StopWorker();
|
||||
void WorkerEvent();
|
||||
|
||||
bool IsEmpty() const;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue