mirror of
https://github.com/PabloMK7/citra.git
synced 2025-09-11 13:20:04 +00:00
kernel: Improvements to process cleanup. (#6680)
* kernel: Properly clean up process threads on exit. * kernel: Track process-owned memory and free on destruction. * apt: Implement DoApplicationJump via home menu when available. * kernel: Move TLS allocation management to owning process.
This commit is contained in:
parent
8b6b58a364
commit
9cb14044ec
11 changed files with 272 additions and 179 deletions
|
@ -988,13 +988,18 @@ ResultCode AppletManager::PrepareToDoApplicationJump(u64 title_id, FS::MediaType
|
|||
// Save the title data to send it to the Home Menu when DoApplicationJump is called.
|
||||
auto application_slot_data = GetAppletSlot(AppletSlot::Application);
|
||||
app_jump_parameters.current_title_id = application_slot_data->title_id;
|
||||
// TODO(Subv): Retrieve the correct media type of the currently-running application. For now
|
||||
// just assume NAND.
|
||||
app_jump_parameters.current_media_type = FS::MediaType::NAND;
|
||||
app_jump_parameters.next_title_id = flags == ApplicationJumpFlags::UseCurrentParameters
|
||||
? application_slot_data->title_id
|
||||
: title_id;
|
||||
app_jump_parameters.next_media_type = media_type;
|
||||
// TODO: Basic heuristic to guess media type, needs proper implementation.
|
||||
app_jump_parameters.current_media_type =
|
||||
((application_slot_data->title_id >> 32) & 0xFFFFFFFF) == 0x00040000
|
||||
? Service::FS::MediaType::SDMC
|
||||
: Service::FS::MediaType::NAND;
|
||||
if (flags == ApplicationJumpFlags::UseCurrentParameters) {
|
||||
app_jump_parameters.next_title_id = app_jump_parameters.current_title_id;
|
||||
app_jump_parameters.next_media_type = app_jump_parameters.current_media_type;
|
||||
} else {
|
||||
app_jump_parameters.next_title_id = title_id;
|
||||
app_jump_parameters.next_media_type = media_type;
|
||||
}
|
||||
app_jump_parameters.flags = flags;
|
||||
|
||||
// Note: The real console uses the Home Menu to perform the application jump, therefore the menu
|
||||
|
@ -1020,45 +1025,51 @@ ResultCode AppletManager::DoApplicationJump(const DeliverArg& arg) {
|
|||
deliver_arg->source_program_id = title_id;
|
||||
}
|
||||
|
||||
// TODO(Subv): Terminate the current Application.
|
||||
if (GetAppletSlot(AppletSlot::HomeMenu)->registered) {
|
||||
// If the home menu is running, use it to jump to the next application.
|
||||
// The home menu will call GetProgramIdOnApplicationJump and
|
||||
// PrepareToStartApplication/StartApplication to launch the title.
|
||||
active_slot = AppletSlot::HomeMenu;
|
||||
SendParameter({
|
||||
.sender_id = AppletId::Application,
|
||||
.destination_id = AppletId::HomeMenu,
|
||||
.signal = SignalType::WakeupToLaunchApplication,
|
||||
});
|
||||
|
||||
// Note: The real console sends signal 17 (WakeupToLaunchApplication) to the Home Menu, this
|
||||
// prompts it to call GetProgramIdOnApplicationJump and
|
||||
// PrepareToStartApplication/StartApplication on the title to launch.
|
||||
active_slot = AppletSlot::Application;
|
||||
// TODO: APT terminates the application here, usually it will exit itself properly though.
|
||||
return RESULT_SUCCESS;
|
||||
} else {
|
||||
// Otherwise, work around the missing home menu by launching the title directly.
|
||||
|
||||
// Perform a soft-reset if we're trying to relaunch the same title.
|
||||
// TODO(Subv): Note that this reboots the entire emulated system, a better way would be to
|
||||
// simply re-launch the title without closing all services, but this would only work for
|
||||
// installed titles since we have no way of getting the file path of an arbitrary game dump
|
||||
// based only on the title id.
|
||||
// TODO: The emulator does not support terminating the old process immediately.
|
||||
// We could call TerminateProcess but references to the process are still held elsewhere,
|
||||
// preventing clean up. This code is left commented for when this is implemented, for now we
|
||||
// cannot use NS as the old process resources would interfere with the new ones.
|
||||
/*
|
||||
auto process =
|
||||
NS::LaunchTitle(app_jump_parameters.next_media_type, app_jump_parameters.next_title_id);
|
||||
if (!process) {
|
||||
LOG_CRITICAL(Service_APT, "Failed to launch title during application jump, exiting.");
|
||||
system.RequestShutdown();
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
*/
|
||||
|
||||
auto new_path = Service::AM::GetTitleContentPath(app_jump_parameters.next_media_type,
|
||||
app_jump_parameters.next_title_id);
|
||||
if (new_path.empty() || !FileUtil::Exists(new_path)) {
|
||||
LOG_CRITICAL(
|
||||
Service_APT,
|
||||
"Failed to find title during application jump: {} Resetting current title instead.",
|
||||
new_path);
|
||||
new_path.clear();
|
||||
auto new_path = Service::AM::GetTitleContentPath(app_jump_parameters.next_media_type,
|
||||
app_jump_parameters.next_title_id);
|
||||
if (new_path.empty() || !FileUtil::Exists(new_path)) {
|
||||
// TODO: This can happen if the requested title is not installed. Need a way to find
|
||||
// non-installed titles in the game list.
|
||||
LOG_CRITICAL(
|
||||
Service_APT,
|
||||
"Failed to find title during application jump: {} Resetting current title instead.",
|
||||
new_path);
|
||||
new_path.clear();
|
||||
}
|
||||
|
||||
system.RequestReset(new_path);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
system.RequestReset(new_path);
|
||||
return RESULT_SUCCESS;
|
||||
|
||||
// Launch the title directly.
|
||||
// The emulator does not suport terminating old processes, would require a lot of cleanup
|
||||
// This code is left commented for when this is implemented, for now we cannot use NS
|
||||
// as the old process resources would interfere with the new ones
|
||||
/*
|
||||
auto process =
|
||||
NS::LaunchTitle(app_jump_parameters.next_media_type, app_jump_parameters.next_title_id);
|
||||
if (!process) {
|
||||
LOG_CRITICAL(Service_APT, "Failed to launch title during application jump, exiting.");
|
||||
system.RequestShutdown();
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
*/
|
||||
}
|
||||
|
||||
ResultCode AppletManager::PrepareToStartApplication(u64 title_id, FS::MediaType media_type) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue