0

Let's say I have an XPC service and two user-visible apps (menu bar item and main app). Both connect to the XPC service.

If both of these app components send a "create Foo" message, how are they dispatched? It's a single process after all, so do they arrive in a sequence or will multiple queues be used?

The XPC service uses Core Data, so I worry about whether I have to create a global queue or ensure thread confinement in any other way.

ctietze
  • 2,805
  • 25
  • 46

1 Answers1

1

Any time you use CoreData, XPC or not, in a non-single-threaded executable you need to address threading, either through confinement, main-thread only, or private queue. Since XPC services don't have as well-defined a concept of a main thread (obviously, there is the first thread which will forever be the main thread, but practically speaking...) NSMainQueueConcurrencyType is probably not useful. I've not seen any indication that any promises are made by XPC about the thread affinity of requests, so I generally proceed under the assumption that the XPC listener's threading management is an implementation detail over which I have no control (until execution transitions into my code). With that in mind, NSConfinementConcurrencyType looks like a bunch of work. So, if it were me, I'd run with NSPrivateQueueConcurrencyType.

Even if you empirically observed only one request executing at once, you would be better off assuming that's not guaranteed.

ipmcc
  • 29,581
  • 5
  • 84
  • 147
  • So I should put all Core Data operations on a queue I control myself to not make any assumptions about the framework. Sounds reasonable. Since private queues have globally unique IDs, this will even work with parallel XPC threads (if such a thing exists), correct? – ctietze Mar 18 '15 at 12:35
  • CoreData provides this mechanism for you. Create an `NSManagedObjectContext` for your XPC service, using `NSPrivateQueueConcurrencyType`, and then use `-performBlock:` and `performBlockAndWait:` to wrap all your interactions with CoreData. – ipmcc Mar 18 '15 at 12:42
  • Didn't know about that! This is great. So in my case I have to simply wrap each action the XPC service in one unit-of-work block, enqueue it, and get rid of race conditions just like that?! Looks good in code, but I can't believe that Core Data's single-thread-per-MOC limitation amounts to that much of a benefit. – ctietze Mar 18 '15 at 14:32