I've got a system extension. There's a daemon that talks to it. Because I want the sysex to be able to reach out on its own, the daemon talks to the sysex over XPC, and passes over an anonymous endpoint, so that either side can initiate a message. This all works pretty well, and I'm happy with it.
But the design, as is, means that if the sysex goes away for some reason, the daemon can't ever talk to it again. This shouldn't be too difficult a problem to fix -- I can tell when the XPC connections are invalidated, I just have to wait for the sysex to come back up. I am using notify(3) for this, and this does work.
And this is the part that is frustrating, and I obviously think should even be impossible: after starting back up, sending a notification, and getting the anonymous endpoint from the daemon, and setting the connection to an NSXPCConnection, the connection ... gets set to nil.
The problem is that since I've written this in Swift, I put an observer on the endpoint and log whenever it changes. And in the log, I see "changing it from nil to ", and then a log message saying "connection is non-nil, as it should be" and then... later it says the connection is nil. Without a "changing it from to nil".
I am very, very frustrated.
Ok. There ended up being multiple instantiations of my NETransparentProxyProvider subclass. The first one, which was causing the problems, still had an XPC listener, and the anonymous XPC connection. In stopProxy, I added code to nil out the invalidation handler, invalidate them, and then set them to nil just for good measure. I must still be missing something, because I added a deinit method that logged it, and it's not being called. sigh.
But! That is how it was being set to nil despite my observing it.
I am much less frustrated now.