Skip to content

Commit 44a2e4d

Browse files
committed
Loader: Only use a single thread when installing packages from an optical drive
1 parent a99fde6 commit 44a2e4d

11 files changed

Lines changed: 36 additions & 32 deletions

File tree

rpcs3/Crypto/unpkg.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,7 @@ void package_reader::extract_worker()
13101310
}
13111311
}
13121312

1313-
package_install_result package_reader::extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths)
1313+
package_install_result package_reader::extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths, bool from_optical_drive)
13141314
{
13151315
package_install_result::error_type error = package_install_result::error_type::no_error;
13161316
usz num_failures = 0;
@@ -1362,7 +1362,8 @@ package_install_result package_reader::extract_data(std::deque<package_reader>&
13621362

13631363
if (reader.m_num_failures == 0)
13641364
{
1365-
const usz thread_count = std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size());
1365+
// Disc archives don't like multithreaded file reads, so let's just use a single thread here
1366+
const usz thread_count = from_optical_drive ? 1 : std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size());
13661367
atomic_t<u32> num_threads_succeeded {0}; // Check if any thread didn't finish. For example when hitting an exception.
13671368

13681369
if (thread_count > 1)

rpcs3/Crypto/unpkg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ class package_reader
372372
const PKGHeader& get_header() const { return m_header; }
373373
const PKGMetaData& get_metadata() const { return m_metadata; }
374374
package_install_result check_target_app_version() const;
375-
static package_install_result extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths);
375+
static package_install_result extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths, bool from_optical_drive);
376376
const psf::registry& get_psf() const { return m_psf; }
377377
result get_result() const { return m_result; };
378378

rpcs3/Emu/System.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
12261226

12271227
std::string inherited_ps3_game_path;
12281228
bool launching_from_disc_archive = false;
1229+
bool launching_from_optical_drive = false;
12291230

12301231
{
12311232
Init();
@@ -1317,7 +1318,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
13171318
std::string disc_info;
13181319
m_ar->serialize(argv.emplace_back(), disc_info, klic.emplace_back(), m_game_dir, hdd1);
13191320

1320-
launching_from_disc_archive = is_iso_file(disc_info);
1321+
launching_from_disc_archive = is_iso_file(disc_info, nullptr, &launching_from_optical_drive);
13211322

13221323
sys_log.notice("Savestate: is iso archive = %d ('%s')", launching_from_disc_archive, disc_info);
13231324

@@ -1623,7 +1624,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
16231624
}
16241625

16251626
const std::string resolved_path = GetCallbacks().resolve_path(m_path);
1626-
if (!launching_from_disc_archive && is_iso_file(m_path))
1627+
if (!launching_from_disc_archive && is_iso_file(m_path, nullptr, &launching_from_optical_drive))
16271628
{
16281629
sys_log.notice("Loading iso archive '%s'", m_path);
16291630

@@ -2100,7 +2101,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
21002101
// Load /dev_bdvd/ from game list if available
21012102
if (std::string game_path = m_games_config.get_path(m_title_id); !game_path.empty())
21022103
{
2103-
if (is_iso_file(game_path))
2104+
if (is_iso_file(game_path, nullptr, &launching_from_optical_drive))
21042105
{
21052106
sys_log.notice("Loading iso archive for patch ('%s')", game_path);
21062107

@@ -2368,9 +2369,9 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
23682369
if (!pkgs.empty())
23692370
{
23702371
bool install_success = true;
2371-
BlockingCallFromMainThread([this, &pkgs, &install_success]()
2372+
BlockingCallFromMainThread([this, &pkgs, &install_success, launching_from_optical_drive]()
23722373
{
2373-
if (!GetCallbacks().on_install_pkgs(pkgs))
2374+
if (!GetCallbacks().on_install_pkgs(pkgs, launching_from_optical_drive))
23742375
{
23752376
install_success = false;
23762377
}

rpcs3/Emu/System.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ struct EmuCallbacks
109109
std::function<std::string(std::string_view)> resolve_path = [](std::string_view arg){ return std::string{arg}; }; // Resolve path using Qt (returns empty string if the file doesn't exist)
110110
std::function<std::string(std::string_view)> resolve_path_may_not_exist = [](std::string_view arg){ return std::string{arg}; }; // Resolve path using Qt
111111
std::function<std::vector<std::string>()> get_font_dirs;
112-
std::function<bool(const std::vector<std::string>&)> on_install_pkgs;
112+
std::function<bool(const std::vector<std::string>&, bool)> on_install_pkgs;
113113
std::function<void(u32)> add_breakpoint;
114114
std::function<bool()> display_sleep_control_supported;
115115
std::function<void(bool)> enable_display_sleep;

rpcs3/Emu/system_utils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ namespace rpcs3::utils
6969
return id;
7070
}
7171

72-
bool install_pkg(const std::string& path)
72+
bool install_pkg(const std::string& path, bool from_optical_drive)
7373
{
7474
sys_log.success("Installing package: %s", path);
7575

@@ -82,7 +82,7 @@ namespace rpcs3::utils
8282
named_thread worker("PKG Installer", [&]
8383
{
8484
std::deque<std::string> bootables;
85-
const package_install_result result = package_reader::extract_data(reader, bootables);
85+
const package_install_result result = package_reader::extract_data(reader, bootables, from_optical_drive);
8686
return result.error == package_install_result::error_type::no_error;
8787
});
8888

rpcs3/Emu/system_utils.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace rpcs3::utils
2525

2626
u32 check_user(std::string_view user);
2727

28-
bool install_pkg(const std::string& path);
28+
bool install_pkg(const std::string& path, bool from_optical_drive);
2929

3030
// VFS directories and disk usage
3131
std::vector<std::pair<std::string, u64>> get_vfs_disk_usage();

rpcs3/Loader/ISO.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ static bool is_iso_file(iso_file& file, u64* size = nullptr)
8484

8585
bool is_iso_file(const std::string& path, u64* size, bool* is_raw_device)
8686
{
87+
if (is_raw_device)
88+
{
89+
*is_raw_device = false;
90+
}
91+
8792
if (path.empty())
8893
{
8994
return false;

rpcs3/main_application.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,11 +428,11 @@ EmuCallbacks main_application::CreateCallbacks()
428428
return font_dirs;
429429
};
430430

431-
callbacks.on_install_pkgs = [](const std::vector<std::string>& pkgs)
431+
callbacks.on_install_pkgs = [](const std::vector<std::string>& pkgs, bool from_optical_drive)
432432
{
433433
for (const std::string& pkg : pkgs)
434434
{
435-
if (!rpcs3::utils::install_pkg(pkg))
435+
if (!rpcs3::utils::install_pkg(pkg, from_optical_drive))
436436
{
437437
sys_log.error("Failed to install %s", pkg);
438438
return false;

rpcs3/rpcs3qt/gui_application.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -946,15 +946,15 @@ void gui_application::InitializeCallbacks()
946946

947947
if (m_show_gui) // If this is false, we already have a fallback in the main_application.
948948
{
949-
callbacks.on_install_pkgs = [this](const std::vector<std::string>& pkgs)
949+
callbacks.on_install_pkgs = [this](const std::vector<std::string>& pkgs, bool from_optical_drive)
950950
{
951951
ensure(!pkgs.empty());
952952
QStringList pkg_list;
953953
for (const std::string& pkg : pkgs)
954954
{
955955
pkg_list << QString::fromStdString(pkg);
956956
}
957-
return main_window::InstallPackages(m_main_window, pkg_list, true);
957+
return main_window::InstallPackages(m_main_window, pkg_list, true, from_optical_drive);
958958
};
959959
}
960960

rpcs3/rpcs3qt/main_window.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ bool main_window::InstallFileInExData(const std::string& extension, const QStrin
881881
return to.commit();
882882
}
883883

884-
bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool from_boot)
884+
bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool from_boot, bool from_optical_drive)
885885
{
886886
if (file_paths.isEmpty())
887887
{
@@ -926,7 +926,7 @@ bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool
926926
return true;
927927
}
928928

929-
return InstallPackages(mw, dir_file_paths, from_boot);
929+
return InstallPackages(mw, dir_file_paths, from_boot, from_optical_drive);
930930
}
931931
}
932932

@@ -986,26 +986,23 @@ bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool
986986

987987
if (from_boot)
988988
{
989-
return HandlePackageInstallation(mw, file_paths, true);
989+
return HandlePackageInstallation(mw, file_paths, true, from_optical_drive);
990990
}
991991

992-
// Handle further installations with a timeout. Otherwise the source explorer instance is not usable during the following file processing.
993992
if (mw)
994993
{
995-
QTimer::singleShot(0, [mw, paths = std::move(file_paths)]()
994+
// Handle further installations with a timeout. Otherwise the source explorer instance is not usable during the following file processing.
995+
QTimer::singleShot(0, [mw, from_optical_drive, paths = std::move(file_paths)]()
996996
{
997-
HandlePackageInstallation(mw, paths, false);
997+
HandlePackageInstallation(mw, paths, false, from_optical_drive);
998998
});
999-
}
1000-
else
1001-
{
1002-
return HandlePackageInstallation(nullptr, file_paths, false);
999+
return true;
10031000
}
10041001

1005-
return true;
1002+
return HandlePackageInstallation(nullptr, file_paths, false, from_optical_drive);
10061003
}
10071004

1008-
bool main_window::HandlePackageInstallation(main_window* mw, QStringList file_paths, bool from_boot)
1005+
bool main_window::HandlePackageInstallation(main_window* mw, QStringList file_paths, bool from_boot, bool from_optical_drive)
10091006
{
10101007
if (file_paths.empty())
10111008
{
@@ -1135,9 +1132,9 @@ bool main_window::HandlePackageInstallation(main_window* mw, QStringList file_pa
11351132
std::deque<std::string> bootable_paths;
11361133

11371134
// Run PKG unpacking asynchronously
1138-
named_thread worker("PKG Installer", [&readers, &result, &bootable_paths]
1135+
named_thread worker("PKG Installer", [&readers, &result, &bootable_paths, from_optical_drive]
11391136
{
1140-
result = package_reader::extract_data(readers, bootable_paths);
1137+
result = package_reader::extract_data(readers, bootable_paths, from_optical_drive);
11411138
return result.error == package_install_result::error_type::no_error;
11421139
});
11431140

0 commit comments

Comments
 (0)