From d63c15d582eb814894632f691fbf8f3a2e81289b Mon Sep 17 00:00:00 2001 From: Lysann Tranvouez Date: Mon, 29 Sep 2025 01:28:30 +0200 Subject: [PATCH] detour_manage_thread --- src/mach_detours.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/mach_detours.c b/src/mach_detours.c index d4b8c09..cf848e9 100644 --- a/src/mach_detours.c +++ b/src/mach_detours.c @@ -405,3 +405,46 @@ mach_error_t detour_transaction_commit_ex(detour_func_t** out_failed_target) } return s_pending_error; } + +mach_error_t detour_manage_thread(thread_t thread) +{ + mach_error_t error; + + // If any of the pending operations failed, then we don't need to do this. + if (s_pending_error != err_none) { + return s_pending_error; + } + + // must be the transaction thread + if (s_transaction_thread != mach_thread_self()) { + return detour_err_wrong_thread; + } + + // Silently (and safely) drop any attempt to suspend our own thread. + if (thread == mach_thread_self()) { + return err_none; + } + + detour_pending_thread* new_pending_thread = malloc(sizeof(detour_pending_thread)); + if (!new_pending_thread) { + error = KERN_RESOURCE_SHORTAGE; + fail: + free(new_pending_thread); + s_pending_error = error; + s_pending_error_pointer = nullptr; + DETOUR_BREAK(); + return error; + } + + error = thread_suspend(thread); + if (error != err_none) { + DETOUR_BREAK(); + goto fail; + } + + new_pending_thread->thread = thread; + new_pending_thread->next = s_pending_threads_head; + s_pending_threads_head = new_pending_thread; + + return err_none; +}