How to safely terminate hanging threads in launched agent context

Hello,

In a launched agent, I need to call into a third‑party library that may occasionally hang. At present, these calls are made from a separate thread, but if the thread hangs it cannot be terminated (pthread_cancel/pthread_kill are ineffective).

Would Apple recommend isolating this functionality in a separate process that can be force‑terminated if it becomes unresponsive, or is there a preferred approach for handling such cases in launched agents? Can I use the system call fork() in launched agent?

Thank you in advance!

Answered by DTS Engineer in 863294022
Would Apple recommend isolating this functionality in a separate process

Well, I’d recommend that you avoid using third-party libraries that “occasionally hang” at all, but I understand that that’s not always an option (-:

If you are stuck with unreliable code then your only option is to run that code in a separate process. Apple platforms do resource tracking on a process-by-process basis, so there’s no way to safely kill a specific thread within your process because that thread might be holding critical resources.

Can I use the system call fork() in launched agent?

Yes, as long as you then immediately call exec*.

WARNING On Apple platforms it is not generally safe to call fork without then immediately calling exec* [1].

But, in general, there’s no specific prohibition against a launchd agent spawning a child process, ideally with posix_spawn or a wrapper around that (including NSTask, Swift Process, and Swift Subprocess).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] One day I’ll collect together my thoughts on this topic into one coherent whole, but for the moment you’ll have to cope with a bunch of random links:

The end of that first thread has links to a relevant Swift Forums discussion and to a research paper that offers valuable insight into the overall issue.

Accepted Answer
Would Apple recommend isolating this functionality in a separate process

Well, I’d recommend that you avoid using third-party libraries that “occasionally hang” at all, but I understand that that’s not always an option (-:

If you are stuck with unreliable code then your only option is to run that code in a separate process. Apple platforms do resource tracking on a process-by-process basis, so there’s no way to safely kill a specific thread within your process because that thread might be holding critical resources.

Can I use the system call fork() in launched agent?

Yes, as long as you then immediately call exec*.

WARNING On Apple platforms it is not generally safe to call fork without then immediately calling exec* [1].

But, in general, there’s no specific prohibition against a launchd agent spawning a child process, ideally with posix_spawn or a wrapper around that (including NSTask, Swift Process, and Swift Subprocess).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] One day I’ll collect together my thoughts on this topic into one coherent whole, but for the moment you’ll have to cope with a bunch of random links:

The end of that first thread has links to a relevant Swift Forums discussion and to a research paper that offers valuable insight into the overall issue.

thank you a lot for the help!

How to safely terminate hanging threads in launched agent context
 
 
Q