Kill XPC when parent app is still running

1.1k Views Asked by At

My parent application uses helper XPC to achieve some task T1. XPC service is implemented using NSXPCConnection. Once the task is complete I don’t need this XPC to be alive. Hence, the parent process calls invalidate on NSXPCConnection object. But, the XPC is still alive even if the connection is invalid. I can see it getting listed in Activity Monitor.

How do I kill this XPC when parent app is still running and it does not require XPC to be alive?

2

There are 2 best solutions below

0
On

Just to be clear, your XPC process will quit when the parent app quits. At least, mine does. Your question is: How to kill it before then?

That is simple: Just call exit(0) in your XPC process immediately after it invokes the completion handler which sends the output back to the parent app. I needed to do this in a project last month, because the XPC process was using an Apple private framework, and exitting it was the only way I could figure to stop a certain undesired and inexplicable (since I have no documentation on the private framework) side effect.

Upon exitting this XPC process, however, I found that, oddly, it continued to run for some milliseconds, and if my parent app opened another connection to this same XPC service in the meantime, the doomed XPC process will accept the new connection just prior to killing itself, leaving the parent app hanging. I've actually seen this happen several times.

So, a follow-up question is: Should you kill it just because you want to be nice? I think the answer is no, according to the following quote from Apple's Daemons and Services Programming Guide > Creating XPC Services

XPC services are managed by launchd, which launches them on demand, restarts them if they crash, and terminates them (by sending SIGKILL) when they are idle.

To summarize: Just invalidate your connections when done, and let launchd worry about killing. Also, don't hold your breath. I've had my app running for the past two hours, and the XPC process, last connection closed two hours ago, is still running.

0
On

XPC Agents by design are meant to be long lived. They automatically reload when they quit or crash based on their KeepAlive setting in the .plist configuration.

Maybe you can register as an Observer for NSWorkspace events:

[[NSWorkspace sharedWorkspace] notificationCenter];

see: NSWorkspace Workspace notifications are posted when:

  • applications are launched and terminated

Then you can disable your XPC Service When your Parent app quits and reenable it when it launches.