diff --git a/headers/os/kernel/OS.h b/headers/os/kernel/OS.h index 6d3a34c5db..cfae3581b4 100644 --- a/headers/os/kernel/OS.h +++ b/headers/os/kernel/OS.h @@ -341,6 +341,8 @@ extern status_t rename_thread(thread_id thread, const char *newName); extern status_t set_thread_priority(thread_id thread, int32 newPriority); extern void exit_thread(status_t status); extern status_t wait_for_thread(thread_id thread, status_t *returnValue); +extern status_t wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, + status_t *_returnCode); extern status_t on_exit_thread(void (*callback)(void *), void *data); extern thread_id find_thread(const char *name); diff --git a/headers/private/kernel/thread.h b/headers/private/kernel/thread.h index a352f2eae0..771d650d1c 100644 --- a/headers/private/kernel/thread.h +++ b/headers/private/kernel/thread.h @@ -127,8 +127,6 @@ thread_id thread_create_thread(const ThreadCreationAttributes& attributes, thread_id spawn_kernel_thread_etc(thread_func, const char *name, int32 priority, void *args, team_id team); -status_t wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, - status_t *_returnCode); status_t select_thread(int32 object, struct select_info *info, bool kernel); status_t deselect_thread(int32 object, struct select_info *info, bool kernel); @@ -147,6 +145,8 @@ status_t _user_resume_thread(thread_id thread); status_t _user_rename_thread(thread_id thread, const char *name); thread_id _user_spawn_thread(struct thread_creation_attributes* attributes); status_t _user_wait_for_thread(thread_id id, status_t *_returnCode); +status_t _user_wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, + status_t *_returnCode); status_t _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags, bigtime_t* _remainingTime); status_t _user_kill_thread(thread_id thread); diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 94e95cbd42..16ad7a2fe1 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -167,6 +167,8 @@ extern status_t _kern_cancel_thread(thread_id threadID, extern void _kern_thread_yield(void); extern status_t _kern_wait_for_thread(thread_id thread, status_t *_returnCode); +extern status_t _kern_wait_for_thread_etc(thread_id thread, uint32 flags, + bigtime_t timeout, status_t *_returnCode); extern bool _kern_has_data(thread_id thread); extern status_t _kern_send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize); diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index bea34448da..db6f4fe3c3 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -3676,6 +3676,28 @@ _user_wait_for_thread(thread_id id, status_t *userReturnCode) } +status_t +_user_wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, status_t *userReturnCode) +{ + status_t returnCode; + status_t status; + + if (userReturnCode != NULL && !IS_USER_ADDRESS(userReturnCode)) + return B_BAD_ADDRESS; + + syscall_restart_handle_timeout_pre(flags, timeout); + + status = wait_for_thread_etc(id, flags | B_CAN_INTERRUPT, timeout, &returnCode); + + if (status == B_OK && userReturnCode != NULL + && user_memcpy(userReturnCode, &returnCode, sizeof(status_t)) < B_OK) { + return B_BAD_ADDRESS; + } + + return syscall_restart_handle_timeout_post(status, timeout); +} + + bool _user_has_data(thread_id thread) { diff --git a/src/system/libroot/os/thread.c b/src/system/libroot/os/thread.c index c278e660f1..9c1cfa0ee8 100644 --- a/src/system/libroot/os/thread.c +++ b/src/system/libroot/os/thread.c @@ -183,6 +183,13 @@ wait_for_thread(thread_id thread, status_t *_returnCode) } +status_t +wait_for_thread_etc(thread_id thread, uint32 flags, bigtime_t timeout, status_t *_returnCode) +{ + return _kern_wait_for_thread_etc(thread, flags, timeout, _returnCode); +} + + status_t on_exit_thread(void (*callback)(void *), void *data) { diff --git a/src/system/libroot/stubbed/libroot_stubs.c b/src/system/libroot/stubbed/libroot_stubs.c index 6fcce6135c..5cd88a1b25 100644 --- a/src/system/libroot/stubbed/libroot_stubs.c +++ b/src/system/libroot/stubbed/libroot_stubs.c @@ -2894,6 +2894,7 @@ void wait_for_debugger() {} void wait_for_objects() {} void wait_for_objects_etc() {} void wait_for_thread() {} +void wait_for_thread_etc() {} void waitid() {} void waitpid() {} void wcpcpy() {} diff --git a/src/system/libroot/stubbed/libroot_stubs_legacy.c b/src/system/libroot/stubbed/libroot_stubs_legacy.c index 4c8cd83e95..ec0ad5d566 100644 --- a/src/system/libroot/stubbed/libroot_stubs_legacy.c +++ b/src/system/libroot/stubbed/libroot_stubs_legacy.c @@ -2841,6 +2841,7 @@ void wait_for_debugger() {} void wait_for_objects() {} void wait_for_objects_etc() {} void wait_for_thread() {} +void wait_for_thread_etc() {} void waitid() {} void waitpid() {} void wcpcpy() {}