Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OS.get_process_exit_code() method #90358

Merged
merged 1 commit into from
Apr 16, 2024

Conversation

KoBeWi
Copy link
Member

@KoBeWi KoBeWi commented Apr 7, 2024

Closes godotengine/godot-proposals#9471
The method is implemented for Windows, Linux, Mac OS, Android. I only tested Windows.

drivers/unix/os_unix.cpp Outdated Show resolved Hide resolved
@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch 3 times, most recently from 9adfbe7 to 8f32c08 Compare April 7, 2024 19:15
doc/classes/OS.xml Outdated Show resolved Hide resolved
doc/classes/OS.xml Outdated Show resolved Hide resolved
@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch from 8f32c08 to 790cd26 Compare April 8, 2024 09:55
@Calinou
Copy link
Member

Calinou commented Apr 8, 2024

it could be implemented for Android, iOS and macOS too.

OS_Unix is the base class of OS_LinuxBSD and OS_MacOS, so the implementation added by this PR should already be used on both macOS and Linux.

@KoBeWi
Copy link
Member Author

KoBeWi commented Apr 8, 2024

Yeah, I forgot to update the description.

doc/classes/OS.xml Outdated Show resolved Hide resolved
@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch from 790cd26 to 880b730 Compare April 8, 2024 20:57
@akien-mga akien-mga changed the title Add get_process_exit_code() method Add OS.get_process_exit_code() method Apr 8, 2024
@lyuma
Copy link
Contributor

lyuma commented Apr 9, 2024

The semantics of waitpid on POSIX style operating systems might need to be explained:
Specifically, not calling get_process_exit_code() may imply that child processes remain in a zombie state, since they require the some sort of wait call to reap the PID... and get_process_exit_code is evidently the call which reaps the zombie.

And calling get_process_exit_code() more than once will fail because a PID can't be reaped more than once.

not saying we need to change the design necessarily, but it might be good to explain these points in the docs. (Or if someone else with good understanding of POSIX style APIs can offer a different explanation)

@bruvzg
Copy link
Member

bruvzg commented Apr 9, 2024

The semantics of waitpid on POSIX style operating systems might need to be explained:
Specifically, not calling get_process_exit_code() may imply that child processes remain in a zombie state, since they require the some sort of wait call to reap the PID... and get_process_exit_code is evidently the call which reaps the zombie.

And calling get_process_exit_code() more than once will fail because a PID can't be reaped more than once.

It is the same for Windows (but instead of kernel, we keep process handles in the process_map), everything is cleared after parent process terminates in both cases. The only part that might be worth mentioning is about calling this and is_process_running methods more than one (after process termination).

@akien-mga
Copy link
Member

Would it make sense to cache the result of querying the exit code or whether the process is running so that calling it multiple times does not cause issues? Or if the OS signals the termination of the process somehow, automatically query and cache it so that those two methods just do system calls while the process is running, and provide the cached result otherwise?

I don't know if that makes sense but it could be a more user-friendly API than purely exposing the system calls with their quirks.

@bruvzg
Copy link
Member

bruvzg commented Apr 9, 2024

Would it make sense to cache the result of querying the exit code or whether the process is running so that calling it multiple times does not cause issues? Or if the OS signals the termination of the process somehow, automatically query and cache it so that those two methods just do system calls while the process is running, and provide the cached result otherwise?

It might be worth caching status (in both is_process_running and get_process_exit_code), since something like this might be used (and won't work w/o caching):

if !OS.is_process_running(...):
    int exit_code = OS.get_process_exit_code(...)
    ...

@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch from 880b730 to 847d5d0 Compare April 9, 2024 09:40
@KoBeWi
Copy link
Member Author

KoBeWi commented Apr 9, 2024

I pushed caching for Windows, but I'm getting same results with and without it.
OSUnix doesn't have convenient process map that can be used for cache.

@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch from 847d5d0 to 9cca6b7 Compare April 9, 2024 09:47
@akien-mga
Copy link
Member

OSUnix doesn't have convenient process map that can be used for cache.

@bruvzg Should we add a similar process map to OS_Unix to achieve that?

@bruvzg
Copy link
Member

bruvzg commented Apr 9, 2024

I pushed caching for Windows, but I'm getting same results with and without it.

It should not be necessary on Windows, only for Unix (I guess as HashMap<pid, status> similarly to Windows process_map).

@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch from 9cca6b7 to f393826 Compare April 9, 2024 20:36
@KoBeWi
Copy link
Member Author

KoBeWi commented Apr 9, 2024

I pushed process map for Unix (not tested).

I guess as HashMap<pid, status>

I made it a struct, because it needs information whether the process is still running (unless there is some exit code that can be assumed to never be returned from app?).

Copy link
Contributor

@lyuma lyuma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am concerned about the additional complexity needed to support this order of operations. In particular, it needs to work from any thread.

Also if there is nothing to clean up data from this HashMap, will it leak?

My personal preference would be to keep the old design and document that you have to pick one or the other function. Use is_process_running only if you do not care about the exit code.

drivers/unix/os_unix.cpp Show resolved Hide resolved
@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch 6 times, most recently from ac1130f to c0a12e9 Compare April 12, 2024 16:16
drivers/unix/os_unix.cpp Outdated Show resolved Hide resolved
@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch from c0a12e9 to 5c2ea79 Compare April 16, 2024 07:58
@akien-mga akien-mga requested a review from bruvzg April 16, 2024 10:02
Copy link
Member

@bruvzg bruvzg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the same mutex should be added to Windows code as well. The rest seems fine.

@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch from 5c2ea79 to 589abe9 Compare April 16, 2024 10:16
@KoBeWi
Copy link
Member Author

KoBeWi commented Apr 16, 2024

Pushed Windows mutex.

Copy link
Member

@bruvzg bruvzg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing mutex lock/unlock around process_map->insert(pid, pi); (2x) and MutextLock in the kill in the Windows code.

@KoBeWi KoBeWi force-pushed the finding_errors_in_other_apps branch from 589abe9 to dce4a3e Compare April 16, 2024 10:46
@KoBeWi
Copy link
Member Author

KoBeWi commented Apr 16, 2024

I forgot to save the file before pushing 🤦‍♂️

@akien-mga akien-mga merged commit 7210d6c into godotengine:master Apr 16, 2024
16 checks passed
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow getting exit value from a spawned process
6 participants