Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to self-terminate a MacOS XPC service?

I've successfully followed the Daemons and Service Guide - Creating XPC Services tutorial, along with the SandboxedFetch sample code and have a working Client / Service setup that is using the new NSXPCConnection class.

What still isn't entirely clear to me is how to properly self-terminate the service application once it has finished its job. I recognize that in many cases, the service is expected to remain alive, but in the use-case I have in mind, the service will be used to only to do some processing that I'd otherwise not perform in the main application. Once that processing is finished, there's no reason for the service application to remain. If the client needs another service at a later date, it can just re-create a new one.

Since the service is a lightweight, non-nibbed, NSApplication, I was trying to self-terminate it by calling invalidate from inside applicationWillTerminate, but that triggers an EXC_BAD_ACCESS exception almost every time. Calling invalidate on the service's [NSXPCListener serviceListener] generates slightly less reliable crashes, but it still crashes.

Calling invalidate from within the client application on its NSXPCConnection also generates an EXC_BAD_ACCESS exception almost every time.

So I'm curious what the correct sequence of steps is to cleanly shutdown the XPC service and then quit the service application. Ideally, the service would self-terminate after it has made its last XPC call to the client.

Attached is a small screenshot of what one of the exception's stacktrace looks like. (Yes, that's a webview that's loading in the service. Once the webview has finished loading, I want the service to self-terminate)

enter image description here

like image 535
kennyc Avatar asked Apr 21 '14 18:04

kennyc


People also ask

What is XPC service on Mac?

macOS uses XPC services for basic inter-process communication between various processes, such as between the XPC Service daemon and third-party application privileged helper tools.

What is XPC services on Iphone?

The XPC Services API provides a lightweight mechanism for basic interprocess communication at the libSystem level. It allows you to create lightweight helper tools, called XPC services, that perform work on behalf of your app.


1 Answers

My first reaction is that you should not bother to terminate. When memory pressure occurs and your service is idle, launchd will kill your service. Exiting probably isn't in anyone's best interest because your service will take time to launch again. Don't terminate and you won't have to figure out why your attempt crashes.

But if for some reason you are determined to terminate, don't try so hard. Just do whatever you need to do to clean up (flush buffers, close network connections gracefully so the server doesn't suffer, whatever) and call exit. Although you seem to be using NSApplication, your service is not an application in any sense that the user cares about and there is no compelling reason to act like one in this respect. The host application needs to be able to cope with your service crashing anyway, so your deliberately exiting unceremoniously is just fine.

By the way, using NSApplication in an XPC service probably isn't the best idea because there's no supported way to declare that you want that. This might help explain why it isn't working as well as you'd like, though this paragraph should not be construed as a proper analysis of the crash. :-)

like image 83
Integer Poet Avatar answered Oct 10 '22 09:10

Integer Poet