Skip to content

Commit e45f390

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

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
@@ -1159,6 +1159,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
11591159

11601160
std::string inherited_ps3_game_path;
11611161
bool launching_from_disc_archive = false;
1162+
bool launching_from_optical_drive = false;
11621163

11631164
{
11641165
Init();
@@ -1250,7 +1251,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
12501251
std::string disc_info;
12511252
m_ar->serialize(argv.emplace_back(), disc_info, klic.emplace_back(), m_game_dir, hdd1);
12521253

1253-
launching_from_disc_archive = is_iso_file(disc_info);
1254+
launching_from_disc_archive = is_iso_file(disc_info, nullptr, &launching_from_optical_drive);
12541255

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

@@ -1556,7 +1557,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
15561557
}
15571558

15581559
const std::string resolved_path = GetCallbacks().resolve_path(m_path);
1559-
if (!launching_from_disc_archive && is_iso_file(m_path))
1560+
if (!launching_from_disc_archive && is_iso_file(m_path, nullptr, &launching_from_optical_drive))
15601561
{
15611562
sys_log.notice("Loading iso archive '%s'", m_path);
15621563

@@ -2033,7 +2034,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
20332034
// Load /dev_bdvd/ from game list if available
20342035
if (std::string game_path = m_games_config.get_path(m_title_id); !game_path.empty())
20352036
{
2036-
if (is_iso_file(game_path))
2037+
if (is_iso_file(game_path, nullptr, &launching_from_optical_drive))
20372038
{
20382039
sys_log.notice("Loading iso archive for patch ('%s')", game_path);
20392040

@@ -2301,9 +2302,9 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
23012302
if (!pkgs.empty())
23022303
{
23032304
bool install_success = true;
2304-
BlockingCallFromMainThread([this, &pkgs, &install_success]()
2305+
BlockingCallFromMainThread([this, &pkgs, &install_success, launching_from_optical_drive]()
23052306
{
2306-
if (!GetCallbacks().on_install_pkgs(pkgs))
2307+
if (!GetCallbacks().on_install_pkgs(pkgs, launching_from_optical_drive))
23072308
{
23082309
install_success = false;
23092310
}

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
@@ -68,7 +68,7 @@ namespace rpcs3::utils
6868
return id;
6969
}
7070

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

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

rpcs3/Emu/system_utils.hpp

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

2424
u32 check_user(std::string_view user);
2525

26-
bool install_pkg(const std::string& path);
26+
bool install_pkg(const std::string& path, bool from_optical_drive);
2727

2828
// VFS directories and disk usage
2929
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
@@ -82,6 +82,11 @@ static bool is_iso_file(iso_file& file, u64* size = nullptr)
8282

8383
bool is_iso_file(const std::string& path, u64* size, bool* is_raw_device)
8484
{
85+
if (is_raw_device)
86+
{
87+
*is_raw_device = false;
88+
}
89+
8590
if (path.empty())
8691
{
8792
return false;

rpcs3/main_application.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,11 +418,11 @@ EmuCallbacks main_application::CreateCallbacks()
418418
return font_dirs;
419419
};
420420

421-
callbacks.on_install_pkgs = [](const std::vector<std::string>& pkgs)
421+
callbacks.on_install_pkgs = [](const std::vector<std::string>& pkgs, bool from_optical_drive)
422422
{
423423
for (const std::string& pkg : pkgs)
424424
{
425-
if (!rpcs3::utils::install_pkg(pkg))
425+
if (!rpcs3::utils::install_pkg(pkg, from_optical_drive))
426426
{
427427
sys_log.error("Failed to install %s", pkg);
428428
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
@@ -875,7 +875,7 @@ bool main_window::InstallFileInExData(const std::string& extension, const QStrin
875875
return to.commit();
876876
}
877877

878-
bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool from_boot)
878+
bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool from_boot, bool from_optical_drive)
879879
{
880880
if (file_paths.isEmpty())
881881
{
@@ -920,7 +920,7 @@ bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool
920920
return true;
921921
}
922922

923-
return InstallPackages(mw, dir_file_paths, from_boot);
923+
return InstallPackages(mw, dir_file_paths, from_boot, from_optical_drive);
924924
}
925925
}
926926

@@ -980,26 +980,23 @@ bool main_window::InstallPackages(main_window* mw, QStringList file_paths, bool
980980

981981
if (from_boot)
982982
{
983-
return HandlePackageInstallation(mw, file_paths, true);
983+
return HandlePackageInstallation(mw, file_paths, true, from_optical_drive);
984984
}
985985

986-
// Handle further installations with a timeout. Otherwise the source explorer instance is not usable during the following file processing.
987986
if (mw)
988987
{
989-
QTimer::singleShot(0, [mw, paths = std::move(file_paths)]()
988+
// Handle further installations with a timeout. Otherwise the source explorer instance is not usable during the following file processing.
989+
QTimer::singleShot(0, [mw, from_optical_drive, paths = std::move(file_paths)]()
990990
{
991-
HandlePackageInstallation(mw, paths, false);
991+
HandlePackageInstallation(mw, paths, false, from_optical_drive);
992992
});
993-
}
994-
else
995-
{
996-
return HandlePackageInstallation(nullptr, file_paths, false);
993+
return true;
997994
}
998995

999-
return true;
996+
return HandlePackageInstallation(nullptr, file_paths, false, from_optical_drive);
1000997
}
1001998

1002-
bool main_window::HandlePackageInstallation(main_window* mw, QStringList file_paths, bool from_boot)
999+
bool main_window::HandlePackageInstallation(main_window* mw, QStringList file_paths, bool from_boot, bool from_optical_drive)
10031000
{
10041001
if (file_paths.empty())
10051002
{
@@ -1129,9 +1126,9 @@ bool main_window::HandlePackageInstallation(main_window* mw, QStringList file_pa
11291126
std::deque<std::string> bootable_paths;
11301127

11311128
// Run PKG unpacking asynchronously
1132-
named_thread worker("PKG Installer", [&readers, &result, &bootable_paths]
1129+
named_thread worker("PKG Installer", [&readers, &result, &bootable_paths, from_optical_drive]
11331130
{
1134-
result = package_reader::extract_data(readers, bootable_paths);
1131+
result = package_reader::extract_data(readers, bootable_paths, from_optical_drive);
11351132
return result.error == package_install_result::error_type::no_error;
11361133
});
11371134

0 commit comments

Comments
 (0)