pm: address review comments.
This commit is contained in:
@@ -86,63 +86,6 @@ namespace sts::pm::impl {
|
||||
this->state = state;
|
||||
}
|
||||
|
||||
void SetSignalOnExit() {
|
||||
this->SetFlag(Flag_SignalOnExit);
|
||||
}
|
||||
|
||||
void SetExceptionOccurred() {
|
||||
this->SetFlag(Flag_ExceptionOccurred);
|
||||
this->SetFlag(Flag_ExceptionWaitingAttach);
|
||||
}
|
||||
|
||||
void ClearExceptionOccurred() {
|
||||
this->ClearFlag(Flag_ExceptionOccurred);
|
||||
}
|
||||
|
||||
void ClearExceptionWaitingAttach() {
|
||||
this->ClearFlag(Flag_ExceptionWaitingAttach);
|
||||
}
|
||||
|
||||
void SetSignalOnDebugEvent() {
|
||||
this->SetFlag(Flag_SignalOnDebugEvent);
|
||||
}
|
||||
|
||||
void SetSuspendedStateChanged() {
|
||||
this->SetFlag(Flag_SuspendedStateChanged);
|
||||
}
|
||||
|
||||
void ClearSuspendedStateChanged() {
|
||||
this->ClearFlag(Flag_SuspendedStateChanged);
|
||||
}
|
||||
|
||||
void SetSuspended() {
|
||||
this->SetFlag(Flag_Suspended);
|
||||
}
|
||||
|
||||
void ClearSuspended() {
|
||||
this->ClearFlag(Flag_Suspended);
|
||||
}
|
||||
|
||||
void SetApplication() {
|
||||
this->SetFlag(Flag_Application);
|
||||
}
|
||||
|
||||
void SetSignalOnStart() {
|
||||
this->SetFlag(Flag_SignalOnStart);
|
||||
}
|
||||
|
||||
void ClearSignalOnStart() {
|
||||
this->ClearFlag(Flag_SignalOnStart);
|
||||
}
|
||||
|
||||
void SetStartedStateChanged() {
|
||||
this->SetFlag(Flag_StartedStateChanged);
|
||||
}
|
||||
|
||||
void ClearStartedStateChanged() {
|
||||
this->ClearFlag(Flag_StartedStateChanged);
|
||||
}
|
||||
|
||||
bool HasStarted() const {
|
||||
return this->state != ProcessState_Created && this->state != ProcessState_CreatedAttached;
|
||||
}
|
||||
@@ -151,41 +94,60 @@ namespace sts::pm::impl {
|
||||
return this->state == ProcessState_Exited;
|
||||
}
|
||||
|
||||
bool ShouldSignalOnExit() const {
|
||||
return this->HasFlag(Flag_SignalOnExit);
|
||||
#define DEFINE_FLAG_SET(flag) \
|
||||
void Set##flag() { \
|
||||
this->SetFlag(Flag_##flag); \
|
||||
}
|
||||
|
||||
bool HasExceptionOccurred() const {
|
||||
return this->HasFlag(Flag_ExceptionOccurred);
|
||||
#define DEFINE_FLAG_GET(get, flag) \
|
||||
bool get##flag() const { \
|
||||
return this->HasFlag(Flag_##flag); \
|
||||
}
|
||||
|
||||
bool HasExceptionWaitingAttach() const {
|
||||
return this->HasFlag(Flag_ExceptionWaitingAttach);
|
||||
#define DEFINE_FLAG_CLEAR(flag) \
|
||||
void Clear##flag() { \
|
||||
this->ClearFlag(Flag_##flag); \
|
||||
}
|
||||
|
||||
bool ShouldSignalOnDebugEvent() const {
|
||||
return this->HasFlag(Flag_SignalOnDebugEvent);
|
||||
DEFINE_FLAG_SET(SignalOnExit)
|
||||
DEFINE_FLAG_GET(Should, SignalOnExit)
|
||||
|
||||
/* This needs a manual setter, because it sets two flags. */
|
||||
void SetExceptionOccurred() {
|
||||
this->SetFlag(Flag_ExceptionOccurred);
|
||||
this->SetFlag(Flag_ExceptionWaitingAttach);
|
||||
}
|
||||
|
||||
bool ShouldSignalOnStart() const {
|
||||
return this->HasFlag(Flag_SignalOnStart);
|
||||
}
|
||||
DEFINE_FLAG_GET(Has, ExceptionOccurred)
|
||||
DEFINE_FLAG_GET(Has, ExceptionWaitingAttach)
|
||||
DEFINE_FLAG_CLEAR(ExceptionOccurred)
|
||||
DEFINE_FLAG_CLEAR(ExceptionWaitingAttach)
|
||||
|
||||
bool HasSuspendedStateChanged() const {
|
||||
return this->HasFlag(Flag_SuspendedStateChanged);
|
||||
}
|
||||
DEFINE_FLAG_SET(SignalOnDebugEvent)
|
||||
DEFINE_FLAG_GET(Should, SignalOnDebugEvent)
|
||||
|
||||
bool IsSuspended() const {
|
||||
return this->HasFlag(Flag_Suspended);
|
||||
}
|
||||
DEFINE_FLAG_SET(SuspendedStateChanged)
|
||||
DEFINE_FLAG_GET(Has, SuspendedStateChanged)
|
||||
DEFINE_FLAG_CLEAR(SuspendedStateChanged)
|
||||
|
||||
bool IsApplication() const {
|
||||
return this->HasFlag(Flag_Application);
|
||||
}
|
||||
DEFINE_FLAG_SET(Suspended)
|
||||
DEFINE_FLAG_GET(Is, Suspended)
|
||||
DEFINE_FLAG_CLEAR(Suspended)
|
||||
|
||||
bool HasStartedStateChanged() const {
|
||||
return this->HasFlag(Flag_StartedStateChanged);
|
||||
}
|
||||
DEFINE_FLAG_SET(Application)
|
||||
DEFINE_FLAG_GET(Is, Application)
|
||||
|
||||
DEFINE_FLAG_SET(SignalOnStart)
|
||||
DEFINE_FLAG_GET(Should, SignalOnStart)
|
||||
DEFINE_FLAG_CLEAR(SignalOnStart)
|
||||
|
||||
DEFINE_FLAG_SET(StartedStateChanged)
|
||||
DEFINE_FLAG_GET(Has, StartedStateChanged)
|
||||
DEFINE_FLAG_CLEAR(StartedStateChanged)
|
||||
|
||||
#undef DEFINE_FLAG_SET
|
||||
#undef DEFINE_FLAG_GET
|
||||
#undef DEFINE_FLAG_CLEAR
|
||||
|
||||
};
|
||||
|
||||
@@ -195,7 +157,7 @@ namespace sts::pm::impl {
|
||||
private:
|
||||
std::shared_ptr<ProcessInfo> process_info;
|
||||
public:
|
||||
ProcessInfoWaiter(std::shared_ptr<ProcessInfo> p) : process_info(p) { /* ... */ }
|
||||
ProcessInfoWaiter(std::shared_ptr<ProcessInfo> p) : process_info(std::move(p)) { /* ... */ }
|
||||
|
||||
/* IWaitable */
|
||||
Handle GetHandle() override {
|
||||
@@ -235,27 +197,27 @@ namespace sts::pm::impl {
|
||||
}
|
||||
|
||||
void Remove(u64 process_id) {
|
||||
for (size_t i = 0; i < this->processes.size(); i++) {
|
||||
if (this->processes[i]->GetProcessId() == process_id) {
|
||||
this->processes.erase(this->processes.begin() + i);
|
||||
for (auto it = this->processes.begin(); it != this->processes.end(); it++) {
|
||||
if ((*it)->GetProcessId() == process_id) {
|
||||
this->processes.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ProcessInfo> Find(u64 process_id) {
|
||||
for (size_t i = 0; i < this->processes.size(); i++) {
|
||||
if (this->processes[i]->GetProcessId() == process_id) {
|
||||
return this->processes[i];
|
||||
for (auto it = this->processes.begin(); it != this->processes.end(); it++) {
|
||||
if ((*it)->GetProcessId() == process_id) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<ProcessInfo> Find(ncm::TitleId title_id) {
|
||||
for (size_t i = 0; i < this->processes.size(); i++) {
|
||||
if (this->processes[i]->GetTitleLocation().title_id == title_id) {
|
||||
return this->processes[i];
|
||||
for (auto it = this->processes.begin(); it != this->processes.end(); it++) {
|
||||
if ((*it)->GetTitleLocation().title_id == title_id) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
@@ -141,20 +141,20 @@ namespace sts::pm::impl {
|
||||
|
||||
/* Process Tracking globals. */
|
||||
HosThread g_process_track_thread;
|
||||
SessionManagerBase *g_process_waitable_manager = nullptr;
|
||||
auto g_process_waitable_manager = WaitableManager(1);
|
||||
|
||||
/* Process lists. */
|
||||
ProcessList g_process_list;
|
||||
ProcessList g_dead_process_list;
|
||||
|
||||
/* Global events. */
|
||||
IEvent *g_process_event = nullptr;
|
||||
IEvent *g_hook_to_create_process_event = nullptr;
|
||||
IEvent *g_hook_to_create_application_process_event = nullptr;
|
||||
IEvent *g_boot_finished_event = nullptr;
|
||||
IEvent *g_process_event = CreateWriteOnlySystemEvent();
|
||||
IEvent *g_hook_to_create_process_event = CreateWriteOnlySystemEvent();
|
||||
IEvent *g_hook_to_create_application_process_event = CreateWriteOnlySystemEvent();
|
||||
IEvent *g_boot_finished_event = CreateWriteOnlySystemEvent();
|
||||
|
||||
/* Process Launch synchronization globals. */
|
||||
IEvent *g_process_launch_start_event = nullptr;
|
||||
IEvent *g_process_launch_start_event = CreateWriteOnlySystemEvent();
|
||||
HosSignal g_process_launch_finish_signal;
|
||||
Result g_process_launch_result = ResultSuccess;
|
||||
LaunchProcessArgs g_process_launch_args = {};
|
||||
@@ -167,13 +167,9 @@ namespace sts::pm::impl {
|
||||
void ProcessTrackingMain(void *arg) {
|
||||
/* This is the main loop of the process tracking thread. */
|
||||
|
||||
/* Create waitable manager. */
|
||||
static auto s_process_waiter = WaitableManager(1);
|
||||
g_process_waitable_manager = &s_process_waiter;
|
||||
|
||||
/* Service processes. */
|
||||
g_process_waitable_manager->AddWaitable(g_process_launch_start_event);
|
||||
g_process_waitable_manager->Process();
|
||||
g_process_waitable_manager.AddWaitable(g_process_launch_start_event);
|
||||
g_process_waitable_manager.Process();
|
||||
}
|
||||
|
||||
inline u32 GetLoaderCreateProcessFlags(u32 launch_flags) {
|
||||
@@ -189,6 +185,18 @@ namespace sts::pm::impl {
|
||||
return ldr_flags;
|
||||
}
|
||||
|
||||
bool HasApplicationProcess() {
|
||||
ProcessListAccessor list(g_process_list);
|
||||
|
||||
for (size_t i = 0; i < list->GetSize(); i++) {
|
||||
if (list[i]->IsApplication()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Result StartProcess(std::shared_ptr<ProcessInfo> process_info, const ldr::ProgramInfo *program_info) {
|
||||
R_TRY(svcStartProcess(process_info->GetHandle(), program_info->main_thread_priority, program_info->default_cpu_id, program_info->main_thread_stack_size));
|
||||
process_info->SetState(ProcessState_Running);
|
||||
@@ -203,7 +211,7 @@ namespace sts::pm::impl {
|
||||
const bool allow_debug = (program_info.flags & ldr::ProgramInfoFlag_AllowDebug) || GetRuntimeFirmwareVersion() < FirmwareVersion_200;
|
||||
|
||||
/* Ensure we only try to run one application. */
|
||||
if (is_application) {
|
||||
if (is_application && HasApplicationProcess()) {
|
||||
return ResultPmApplicationRunning;
|
||||
}
|
||||
|
||||
@@ -268,7 +276,7 @@ namespace sts::pm::impl {
|
||||
{
|
||||
ProcessListAccessor list(g_process_list);
|
||||
list->Add(process_info);
|
||||
g_process_waitable_manager->AddWaitable(new ProcessInfoWaiter(process_info));
|
||||
g_process_waitable_manager.AddWaitable(new ProcessInfoWaiter(process_info));
|
||||
}
|
||||
|
||||
*args->out_process_id = process_id;
|
||||
@@ -395,7 +403,7 @@ namespace sts::pm::impl {
|
||||
Result LaunchTitle(u64 *out_process_id, const ncm::TitleLocation &loc, u32 flags) {
|
||||
/* Ensure we only try to launch one title at a time. */
|
||||
static HosMutex s_lock;
|
||||
std::scoped_lock<HosMutex> lk(s_lock);
|
||||
std::scoped_lock lk(s_lock);
|
||||
|
||||
/* Set global arguments, signal, wait. */
|
||||
g_process_launch_args = {
|
||||
|
||||
Reference in New Issue
Block a user