Processes & Concurrency

RSS for tag

Discover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.

Concurrency Documentation

Posts under Processes & Concurrency subtopic

Post

Replies

Boosts

Views

Created

Unable to set subtitle when BGContinuedProcessingTask expires
Hi, I've now identified a few areas when BGContinuedProcessingTask gets expired by the system no progress for ~30 seconds high CPU usage high temperature Some of these I can preempt and expire preemptively and handle the notification, others I cannot and just need to let the failure bubble up. When the failure does bubble up, I'd like to update the title and subtitle. I'm able to update the title, but the subtitle is fixed at "Task Failed" Is there any workaround? Or shall I file a bug here?
0
0
145
Feb ’26
Trouble creating an XPC service for out-of-process rendering
I'm working on an editor for Bevy games and wanted the following workflow: Launch the game process Host a Metal view for the game's render target Use an XPC service to transfer an MTLSharedTextureHandle Keep the connection for editor/game communication and hot reload As such I created the following editor service: public let XPCEditorServiceName = "org.bevy.editor" public enum XPCEditorMessage: Codable { case ping } public enum XPCEditorReply: Codable { case pong } extension XPCListener { static let bevy = try! XPCListener(service: XPCEditorServiceName) { request in request.accept(XPCEditorService.init) } } struct XPCEditorService: XPCPeerHandler { let session: XPCSession private func handle(_ message: XPCEditorMessage) -> XPCEditorReply? { switch message { case .ping: return .pong } } func handleIncomingRequest(_ message: XPCReceivedMessage) -> (any Encodable)? { do { return handle(try message.decode()) } catch { return nil } } func handleCancellation(error: XPCRichError) { print(error) } } and I initialize it in my app's App initializer: // Launch the XPC service print(XPCListener.bevy) I wanted to test this using an executable target with the following main.swift: let session = try XPCSession(xpcService: XPCEditorServiceName) let response: XPCEditorReply = try session.sendSync(XPCEditorMessage.ping) print("Connected to editor!") The editor prints Listener<org.bevy.editor>(Active) but the game fails with Underlying connection was invalidated. Reason: Connection init failed at lookup with error 3 - No such process What am I doing wrong? PS. Would also appreciate an example of sending & rendering the MTLSharedTextureHandle both in editor & game.
2
0
127
Feb ’26
Migrating away from SMJobBless
I have migrated my code to use SMAppService but am running into trouble deleting the old SMJobBless launchd registration using launchd remove. I am invoking this from a root shell when I detect the daemon and associated plist still exist, then also deleting those files. The remove seems to work (i.e. no errors returned) but launchd list shows the service is registered, with a status code of 28 I am using the same label for SMAppService as previously and suspect this is the reason for the problem. However, I am reluctant to change the label as there will a lot of code changes to do this. If I quit my application, disable the background job in System Settings and run sudo launchd remove in the Terminal then it is removed and my application runs as expected once the background job is re-enabled. Alternatively, a reboot seems to get things going. Any suggestions on to how I could do this more effectively welcome.
2
0
126
Mar ’26
Unix Domain Socket path for IPC between LaunchDaemon and LaunchAgent
Hello, I am working on a cross-platform application where IPC between a LaunchDaemon and a LaunchAgent is implemented via Unix domain sockets. On macOS, the socket path length is restricted to 104 characters. What is the Apple-recommended directory for these sockets to ensure the path remains under the limit while allowing a non-sandboxed agent to communicate with a root daemon? Standard paths like $TMPDIR are often too long for this purpose. Thank you in advance!
4
0
195
Mar ’26
Clarification on concurrency guarantees for shared data between App and Widget extensions
Hi, I’m looking for clarification on what concurrency and consistency guarantees Apple provides when multiple targets (main app + Widget extensions) access shared storage. Specifically: 1. UserDefaults (App Group / suiteName:) • If multiple processes (app + multiple widget instances) read and write the same shared UserDefaults, what guarantees are provided? • Is access serialized internally to prevent corruption? • Are read–modify–write operations safe across processes, or can lost updates occur? 2. Core Data (shared SQLite store in App Group container) • Is it officially supported for multiple processes to open and write to the same Core Data SQLite store? • Are there recommended configurations (e.g. WAL mode) for safe multi-process access? • Is Apple’s recommendation to have a single writer process? 3. FileManager (shared container files) • If two processes write to the same file in an App Group container, what guarantees are provided by the system? • Is atomic replaceItemAt the recommended pattern for safe cross-process updates? Additionally: • Do multiple widget instances count as separate processes with respect to these guarantees? • Is there official guidance on best practices for shared persistence between app and widget extensions? I want to ensure I’m following the correct architecture and not relying on undefined behavior. Thanks.
1
0
147
Mar ’26
How to launch a sandboxed process as a standalone application?
Hello, I have an application that needs to be published to the App Store. This application consists of two processes, A and B, where B is a child process of A. I found that if process B needs to be launched as a child process of A in sandbox mode, it is necessary to set the following keys in the entitlements.plist file: <key>com.apple.security.app-sandbox</key><true/><key>com.apple.security.inherit</key><true/> However, after setting these keys, process B can no longer be launched directly. This issue is particularly prominent because process B has a window and a Dock icon — in this case, if the user pins the Dock icon, they will be unable to launch process B. Could you please advise on a solution to this problem?
1
0
139
4w
BGProcessingTask expirationHandler — No way to distinguish expiration reason
The expirationHandler on BGProcessingTask is a () -> Void closure. It provides no information about why it was called. In my testing, all of the following trigger the same handler: Time expiration Resource pressure (CPU, memory, battery) Not reporting progress User tapping "Stop" on the Live Activity There is no way for the app to tell these apart. Questions: Q1. Is there an official, complete list of all conditions that trigger expirationHandler? The documentation only mentions "time expires." Q2. What is the specific time limit before timeout? If it varies by device state, what are the conditions? Q3. A way to distinguish the reason is needed. "User stop" and "system expiration" require completely different handling. Currently this is impossible. Environment: iOS 26, physical device
1
0
83
3w
BGProcessingTask expirationHandler — No way to distinguish expiration reason
The expirationHandler on BGProcessingTask is a () -> Void closure. It provides no information about why it was called. In my testing, all of the following trigger the same handler: Time expiration Resource pressure (CPU, memory, battery) Not reporting progress User tapping "Stop" on the Live Activity There is no way for the app to tell these apart. Questions: Q1. Is there an official, complete list of all conditions that trigger expirationHandler? The documentation only mentions "time expires." Q2. What is the specific time limit before timeout? If it varies by device state, what are the conditions? Q3. A way to distinguish the reason is needed. "User stop" and "system expiration" require completely different handling. Currently this is impossible. Environment: iOS 26, physical device
5
0
175
3w
Background upload issue in WatchOS
We are developing a watchOS application that records long audio sessions and uploads them to our backend in chunks (~5 MB each) using pre-signed URLs and URLSession background upload. Current behavior: While audio recording is active, uploads continue successfully even when the app is in the background. Once the recording stops, if multiple chunks (e.g., 10+) are still pending, the remaining uploads do not proceed in the background and appear to be suspended. We attempted to use WKExtendedRuntimeSession (mindfulness type) to allow sufficient time to enqueue background upload tasks, but the session is invalidated when the app goes to the background (e.g., wrist down or app inactive), which prevents reliable scheduling of uploads. Additionally, we added the entitlement: com.apple.developer.extended-runtime-session (mindfulness) in the Watch app entitlements file, but Xcode automatic signing fails with: “Provisioning profile does not include the com.apple.developer.extended-runtime-session entitlement.” It appears that the provisioning profile is not being updated to include this entitlement. Our questions: Is WKExtendedRuntimeSession (mindfulness) expected to support scheduling background URLSession uploads after the app goes to background? How should we reliably complete pending background uploads on watchOS after a long recording session ends? Is there any additional entitlement or recommended approach for this use case? Why is the extended runtime entitlement not being applied to the provisioning profile despite being added in the entitlements file? We are aiming to follow Apple-recommended practices for long-running tasks and background uploads on watchOS. Any guidance would be greatly appreciated.
2
0
158
2w
Securing XPC Daemon Communication from Authorization Plugin
I'm working on securing communication between an Authorization Plugin and an XPC daemon, and I’d appreciate some guidance on best practices and troubleshooting. The current design which, I’ve implemented a custom Authorization Plugin for step-up authentication, which is loaded by Authorization Services at the loginwindow (inside SecurityAgent). This plugin acts as an XPC client and connects to a custom XPC daemon. Setup Details 1. XPC Daemon Runs as root (LaunchDaemon) Not sandboxed (my understanding is that root daemons typically don’t run sandboxed—please correct me if this is wrong) Mach service: com.roboInc.AuthXpcDaemon Bundle identifier: com.roboInc.OfflineAuthXpcDaemon 2. Authorization Plugin Bundle identifier: com.roboInc.AuthPlugin Loaded by SecurityAgent during login 3. Code Signing Both plugin and daemon are signed using a development certificate What I’m Trying to Achieve I want to secure the XPC communication so that: The daemon only accepts connections from trusted clients The plugin only connects to the legitimate daemon Communication is protected against unauthorized access The Issue I'm facing I attempted to validate code signatures using: SecRequirementCreateWithString SecCodeCopyGuestWithAttributes SecCodeCheckValidity However, validation consistently fails with: -67050 (errSecCSReqFailed) Could you please help here What is the recommended way to securely authenticate an Authorization Plugin (running inside SecurityAgent) to a privileged XPC daemon? Since the plugin runs inside SecurityAgent, how can the daemon reliably distinguish my plugin from other plugins? What is the correct approach to building a SecRequirement in this scenario? Any guidance, examples, or pointers would be greatly appreciated. Thanks in advance!
6
0
227
2w
FIFinderSync Extension fails to load on FIFinderSync Extension fails to load on macOS 26.3.1 (a) (25D771280a)
(! status in pluginkit, FinderSyncExtensionHost process missing) macOS Version: 26.3.1 Beta (25D771280a) Xcode Version: 16.3 (17C529) Steps to reproduce: Create a Finder Sync Extension project Build and install to /Applications Enable in System Settings → Extensions → Finder Extensions Extension shows ! in pluginkit output FinderSyncExtensionHost process never starts Context menu never appears in Finder Expected: Extension loads and context menu appears Actual: Extension marked with ! in pluginkit, no process launched pluginkit output: ! com.github.astronautJack.EasyNewFile.EasyNewFileExtension(1.0)
1
0
71
2w
How to debug a Launch Daemon that requires an App Group provisioning profile for XPC communication
Hello, I am developing a macOS Launch Daemon (packaged as a bundle) that acts as an XPC server. For debugging purposes, I am trying to run the daemon's executable directly from the terminal via sudo ./mydaemon.app/Contents/MacOS/myexecutable. Initially, I added the com.apple.security.application-groups entitlement to the daemon. However, when starting the process, it failed to create the XPC service with the following errors: Unsatisfied entitlements: com.apple.security.application-groups Soft-restriction provisioning profile validation failure: Error Domain=AppleMobileFileIntegrityError Code=-413 "No matching profile found" UserInfo={NSURL=, unsatisfiedEntitlements=, NSLocalizedDescription=No matching profile found} listener failed to activate: xpc_error=[1: Operation not permitted] To resolve the profile validation failure, I registered a new App Group in the Apple Developer Portal, generated a new provisioning profile for the daemon that includes this group, and embedded it into the bundle (Contents/embedded.provisionprofile). Now, the previous profile error is gone, but I am getting a new identity conflict error, and the XPC listener still fails: Two equal instances have unequal identities. <anon<myproc_name>(501) pid=2818 AUID=501> and <anon<myproc_name>(501)(262) pid=2818 AUID=262> listener failed to activate: xpc_error=[1: Operation not permitted] My questions are: What exactly causes the Two equal instances have unequal identities error? I noticed the Audit UID difference (AUID=501 vs AUID=262). Why does NSXPCListener still fail with Operation not permitted? What is the recommended workflow for debugging a Launch Daemon that requires an App Group provisioning profile for XPC communication? Thank you in advance!
2
0
81
1w
Unable to set subtitle when BGContinuedProcessingTask expires
Hi, I've now identified a few areas when BGContinuedProcessingTask gets expired by the system no progress for ~30 seconds high CPU usage high temperature Some of these I can preempt and expire preemptively and handle the notification, others I cannot and just need to let the failure bubble up. When the failure does bubble up, I'd like to update the title and subtitle. I'm able to update the title, but the subtitle is fixed at "Task Failed" Is there any workaround? Or shall I file a bug here?
Replies
0
Boosts
0
Views
145
Activity
Feb ’26
Trouble creating an XPC service for out-of-process rendering
I'm working on an editor for Bevy games and wanted the following workflow: Launch the game process Host a Metal view for the game's render target Use an XPC service to transfer an MTLSharedTextureHandle Keep the connection for editor/game communication and hot reload As such I created the following editor service: public let XPCEditorServiceName = "org.bevy.editor" public enum XPCEditorMessage: Codable { case ping } public enum XPCEditorReply: Codable { case pong } extension XPCListener { static let bevy = try! XPCListener(service: XPCEditorServiceName) { request in request.accept(XPCEditorService.init) } } struct XPCEditorService: XPCPeerHandler { let session: XPCSession private func handle(_ message: XPCEditorMessage) -> XPCEditorReply? { switch message { case .ping: return .pong } } func handleIncomingRequest(_ message: XPCReceivedMessage) -> (any Encodable)? { do { return handle(try message.decode()) } catch { return nil } } func handleCancellation(error: XPCRichError) { print(error) } } and I initialize it in my app's App initializer: // Launch the XPC service print(XPCListener.bevy) I wanted to test this using an executable target with the following main.swift: let session = try XPCSession(xpcService: XPCEditorServiceName) let response: XPCEditorReply = try session.sendSync(XPCEditorMessage.ping) print("Connected to editor!") The editor prints Listener<org.bevy.editor>(Active) but the game fails with Underlying connection was invalidated. Reason: Connection init failed at lookup with error 3 - No such process What am I doing wrong? PS. Would also appreciate an example of sending & rendering the MTLSharedTextureHandle both in editor & game.
Replies
2
Boosts
0
Views
127
Activity
Feb ’26
Migrating away from SMJobBless
I have migrated my code to use SMAppService but am running into trouble deleting the old SMJobBless launchd registration using launchd remove. I am invoking this from a root shell when I detect the daemon and associated plist still exist, then also deleting those files. The remove seems to work (i.e. no errors returned) but launchd list shows the service is registered, with a status code of 28 I am using the same label for SMAppService as previously and suspect this is the reason for the problem. However, I am reluctant to change the label as there will a lot of code changes to do this. If I quit my application, disable the background job in System Settings and run sudo launchd remove in the Terminal then it is removed and my application runs as expected once the background job is re-enabled. Alternatively, a reboot seems to get things going. Any suggestions on to how I could do this more effectively welcome.
Replies
2
Boosts
0
Views
126
Activity
Mar ’26
Unix Domain Socket path for IPC between LaunchDaemon and LaunchAgent
Hello, I am working on a cross-platform application where IPC between a LaunchDaemon and a LaunchAgent is implemented via Unix domain sockets. On macOS, the socket path length is restricted to 104 characters. What is the Apple-recommended directory for these sockets to ensure the path remains under the limit while allowing a non-sandboxed agent to communicate with a root daemon? Standard paths like $TMPDIR are often too long for this purpose. Thank you in advance!
Replies
4
Boosts
0
Views
195
Activity
Mar ’26
Clarification on concurrency guarantees for shared data between App and Widget extensions
Hi, I’m looking for clarification on what concurrency and consistency guarantees Apple provides when multiple targets (main app + Widget extensions) access shared storage. Specifically: 1. UserDefaults (App Group / suiteName:) • If multiple processes (app + multiple widget instances) read and write the same shared UserDefaults, what guarantees are provided? • Is access serialized internally to prevent corruption? • Are read–modify–write operations safe across processes, or can lost updates occur? 2. Core Data (shared SQLite store in App Group container) • Is it officially supported for multiple processes to open and write to the same Core Data SQLite store? • Are there recommended configurations (e.g. WAL mode) for safe multi-process access? • Is Apple’s recommendation to have a single writer process? 3. FileManager (shared container files) • If two processes write to the same file in an App Group container, what guarantees are provided by the system? • Is atomic replaceItemAt the recommended pattern for safe cross-process updates? Additionally: • Do multiple widget instances count as separate processes with respect to these guarantees? • Is there official guidance on best practices for shared persistence between app and widget extensions? I want to ensure I’m following the correct architecture and not relying on undefined behavior. Thanks.
Replies
1
Boosts
0
Views
147
Activity
Mar ’26
How to launch a sandboxed process as a standalone application?
Hello, I have an application that needs to be published to the App Store. This application consists of two processes, A and B, where B is a child process of A. I found that if process B needs to be launched as a child process of A in sandbox mode, it is necessary to set the following keys in the entitlements.plist file: <key>com.apple.security.app-sandbox</key><true/><key>com.apple.security.inherit</key><true/> However, after setting these keys, process B can no longer be launched directly. This issue is particularly prominent because process B has a window and a Dock icon — in this case, if the user pins the Dock icon, they will be unable to launch process B. Could you please advise on a solution to this problem?
Replies
1
Boosts
0
Views
139
Activity
4w
BGProcessingTask expirationHandler — No way to distinguish expiration reason
The expirationHandler on BGProcessingTask is a () -> Void closure. It provides no information about why it was called. In my testing, all of the following trigger the same handler: Time expiration Resource pressure (CPU, memory, battery) Not reporting progress User tapping "Stop" on the Live Activity There is no way for the app to tell these apart. Questions: Q1. Is there an official, complete list of all conditions that trigger expirationHandler? The documentation only mentions "time expires." Q2. What is the specific time limit before timeout? If it varies by device state, what are the conditions? Q3. A way to distinguish the reason is needed. "User stop" and "system expiration" require completely different handling. Currently this is impossible. Environment: iOS 26, physical device
Replies
1
Boosts
0
Views
83
Activity
3w
BGProcessingTask expirationHandler — No way to distinguish expiration reason
The expirationHandler on BGProcessingTask is a () -> Void closure. It provides no information about why it was called. In my testing, all of the following trigger the same handler: Time expiration Resource pressure (CPU, memory, battery) Not reporting progress User tapping "Stop" on the Live Activity There is no way for the app to tell these apart. Questions: Q1. Is there an official, complete list of all conditions that trigger expirationHandler? The documentation only mentions "time expires." Q2. What is the specific time limit before timeout? If it varies by device state, what are the conditions? Q3. A way to distinguish the reason is needed. "User stop" and "system expiration" require completely different handling. Currently this is impossible. Environment: iOS 26, physical device
Replies
5
Boosts
0
Views
175
Activity
3w
Background upload issue in WatchOS
We are developing a watchOS application that records long audio sessions and uploads them to our backend in chunks (~5 MB each) using pre-signed URLs and URLSession background upload. Current behavior: While audio recording is active, uploads continue successfully even when the app is in the background. Once the recording stops, if multiple chunks (e.g., 10+) are still pending, the remaining uploads do not proceed in the background and appear to be suspended. We attempted to use WKExtendedRuntimeSession (mindfulness type) to allow sufficient time to enqueue background upload tasks, but the session is invalidated when the app goes to the background (e.g., wrist down or app inactive), which prevents reliable scheduling of uploads. Additionally, we added the entitlement: com.apple.developer.extended-runtime-session (mindfulness) in the Watch app entitlements file, but Xcode automatic signing fails with: “Provisioning profile does not include the com.apple.developer.extended-runtime-session entitlement.” It appears that the provisioning profile is not being updated to include this entitlement. Our questions: Is WKExtendedRuntimeSession (mindfulness) expected to support scheduling background URLSession uploads after the app goes to background? How should we reliably complete pending background uploads on watchOS after a long recording session ends? Is there any additional entitlement or recommended approach for this use case? Why is the extended runtime entitlement not being applied to the provisioning profile despite being added in the entitlements file? We are aiming to follow Apple-recommended practices for long-running tasks and background uploads on watchOS. Any guidance would be greatly appreciated.
Replies
2
Boosts
0
Views
158
Activity
2w
Securing XPC Daemon Communication from Authorization Plugin
I'm working on securing communication between an Authorization Plugin and an XPC daemon, and I’d appreciate some guidance on best practices and troubleshooting. The current design which, I’ve implemented a custom Authorization Plugin for step-up authentication, which is loaded by Authorization Services at the loginwindow (inside SecurityAgent). This plugin acts as an XPC client and connects to a custom XPC daemon. Setup Details 1. XPC Daemon Runs as root (LaunchDaemon) Not sandboxed (my understanding is that root daemons typically don’t run sandboxed—please correct me if this is wrong) Mach service: com.roboInc.AuthXpcDaemon Bundle identifier: com.roboInc.OfflineAuthXpcDaemon 2. Authorization Plugin Bundle identifier: com.roboInc.AuthPlugin Loaded by SecurityAgent during login 3. Code Signing Both plugin and daemon are signed using a development certificate What I’m Trying to Achieve I want to secure the XPC communication so that: The daemon only accepts connections from trusted clients The plugin only connects to the legitimate daemon Communication is protected against unauthorized access The Issue I'm facing I attempted to validate code signatures using: SecRequirementCreateWithString SecCodeCopyGuestWithAttributes SecCodeCheckValidity However, validation consistently fails with: -67050 (errSecCSReqFailed) Could you please help here What is the recommended way to securely authenticate an Authorization Plugin (running inside SecurityAgent) to a privileged XPC daemon? Since the plugin runs inside SecurityAgent, how can the daemon reliably distinguish my plugin from other plugins? What is the correct approach to building a SecRequirement in this scenario? Any guidance, examples, or pointers would be greatly appreciated. Thanks in advance!
Replies
6
Boosts
0
Views
227
Activity
2w
FIFinderSync Extension fails to load on FIFinderSync Extension fails to load on macOS 26.3.1 (a) (25D771280a)
(! status in pluginkit, FinderSyncExtensionHost process missing) macOS Version: 26.3.1 Beta (25D771280a) Xcode Version: 16.3 (17C529) Steps to reproduce: Create a Finder Sync Extension project Build and install to /Applications Enable in System Settings → Extensions → Finder Extensions Extension shows ! in pluginkit output FinderSyncExtensionHost process never starts Context menu never appears in Finder Expected: Extension loads and context menu appears Actual: Extension marked with ! in pluginkit, no process launched pluginkit output: ! com.github.astronautJack.EasyNewFile.EasyNewFileExtension(1.0)
Replies
1
Boosts
0
Views
71
Activity
2w
How to debug a Launch Daemon that requires an App Group provisioning profile for XPC communication
Hello, I am developing a macOS Launch Daemon (packaged as a bundle) that acts as an XPC server. For debugging purposes, I am trying to run the daemon's executable directly from the terminal via sudo ./mydaemon.app/Contents/MacOS/myexecutable. Initially, I added the com.apple.security.application-groups entitlement to the daemon. However, when starting the process, it failed to create the XPC service with the following errors: Unsatisfied entitlements: com.apple.security.application-groups Soft-restriction provisioning profile validation failure: Error Domain=AppleMobileFileIntegrityError Code=-413 "No matching profile found" UserInfo={NSURL=, unsatisfiedEntitlements=, NSLocalizedDescription=No matching profile found} listener failed to activate: xpc_error=[1: Operation not permitted] To resolve the profile validation failure, I registered a new App Group in the Apple Developer Portal, generated a new provisioning profile for the daemon that includes this group, and embedded it into the bundle (Contents/embedded.provisionprofile). Now, the previous profile error is gone, but I am getting a new identity conflict error, and the XPC listener still fails: Two equal instances have unequal identities. <anon<myproc_name>(501) pid=2818 AUID=501> and <anon<myproc_name>(501)(262) pid=2818 AUID=262> listener failed to activate: xpc_error=[1: Operation not permitted] My questions are: What exactly causes the Two equal instances have unequal identities error? I noticed the Audit UID difference (AUID=501 vs AUID=262). Why does NSXPCListener still fail with Operation not permitted? What is the recommended workflow for debugging a Launch Daemon that requires an App Group provisioning profile for XPC communication? Thank you in advance!
Replies
2
Boosts
0
Views
81
Activity
1w