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

Activity

Re-enrolling a LaunchDaemon, does it require user auth?
I am building an app that uses the SMAppService to register a LaunchDaemon that is bundled with my .app. I've got a priming flow created which walks the user through approving the service so that it will start on login. However, I need to also be able to upgrade this background service if the user updates the app. To do this, I think I need to call unregisterAndReturnError and then registerAndReturnError. From my testing, this seems to work correctly, but I have a concern. Will the user ever be prompted to re-authorize the LaunchDaemon that I am registering? If so, under what circumstances will that happen, and what does it look like (so that I can guide the user through it)?
5
0
322
May ’25
LaunchAgent can't connect to CloudKit daemon
For this code: let status = try await container.accountStatus() Seeing this error: 2025-05-08 15:32:00.945731-0500 localhost myAgent[2661]: (myDaemon.debug.dylib) [com.myDaemon.cli:networking] Error Domain=CKErrorDomain Code=6 "Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error." UserInfo={NSLocalizedDescription=Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error., CKRetryAfter=5, CKErrorDescription=Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error., NSUnderlyingError=0x600001bfc270 {Error Domain=NSCocoaErrorDomain Code=4099 UserInfo={NSDebugDescription= I initially started the this process as System Daemon to see what would happen (which obviously does not have CloudKit features). Then moved it back to /Library/LaunchAgents/ and can't get rid of that error. I see also following message from CloudKit daemon: Ignoring failed attempt to get container proxy for <private>: Error Domain=NSCocoaErrorDomain Code=4099 UserInfo={NSDebugDescription=<private>} Automatically retrying getting container proxy due to error for <private>: Error Domain=NSCocoaErrorDomain Code=4099 UserInfo={NSDebugDescription=<private>} XPC connection interrupted for <private> And this error for xpc service: [0x130e074b0] failed to do a bootstrap look-up: xpc_error=[3: No such process] If I start the same cli process directly from XCode, then it works just fine.
3
0
168
May ’25
SMAppService getting notified when status changes externally (from System Settings)
Say I want to sync a toggle in my app with SMAppService's .status property. If the status changes from my app I can track it. But if user toggles it from System Settings, I don't see a notification so then the UI in my app is out of date. The status property is not key value observable and there doesn't appear to be a SMAppServiceStatusDidChangeNotification ? I can re-read it every time my app will become active but feels kind of wrong to do it this way.
2
0
88
May ’25
XPC activity doesn’t fire while main app is closed
Hi, I have a sandboxed app with a bundled sandboxed XPC service. When it’s launched, the XPC service registers a repeating XPC activity with the system. The activity’s handler block does get called regularly like I’d expect, but it stops being called once the main app terminates. What’s the recommended way to fix this issue? Could I have a bundled XPC service double as a launch agent, or would that cause other problems?
4
0
157
May ’25
XPC Service Cleanup and Freeing Memory
I have used C APIs to create a XPC server(mach service) as a launch daemon. I use dispatch_source_create () followed by dispatch_resume() to start the listener. I dont have any code for cleaning up memory. I want to make sure that the XPC server is shutdown gracefully, without any memory leaks. I know that launchd handles the cycle and the XPC framework takes care of XPC objects. But do I need to do additional cleanup when the XPC listener is shutdown ?
7
0
510
Mar ’25
BGContinuedProcessingTask does not respect fractionCompleted to keep alive
I posted here https://developer.apple.com/forums/thread/805554?page=1#867766022 but posting again for visibility (and let me know how I can file a bug) There was a response in that thread that said you could use the childProgress system to help updating progresses to keep the backgroundTask alive. What I've found is that using childProgresses results in more terminations than if you just updated the progress directly. Here is my setups to test this A BGContinuedProcessingTask that uses URLSessions to upload, and registers the task.progress with the Urlsession Progress Same, but the task.progress gets updated via a UrlSession Callback The second is MUCH more stable out in the field in cellular settings, the first fails extremely frequently. My suspicion is that in the documentation here https://developer.apple.com/documentation/foundation/progress#Reporting-Progress-for-Multiple-Operations it explicitly states The completedUnitCount property for a containing progress object only updates when the suboperation is 100% complete. The fractionCompleted property for a containing progress object updates continuously as work progresses for all suboperations. I wonder if BGContinuedProcessingTask is only looking at completedUnitCount for progress, and not fractionCompleted? In either case, I would love to use the childProgresses because there are bugs with retries by updating the progress manually, so would love some help resolving this, Thanks!
3
0
159
4w
Feature Request: Reason for taskExpiration for BGContinuedProcessingTask
I've tuned my task to be decently resilient, but I found a few issues that caused it to expire regularly. excessive CPU usage -> I'm actually running it behind ReactNative, and I found an issue where I was still updating ReactNative and thus it was keeping it alive the entire time the task was running. Removing this update helped improve stability not updating progress frequently enough ( see https://developer.apple.com/forums/thread/809182?page=1#868247022) My feature request is, would it be possible to get a reason the task was expired in task.expirationHandler? That would be helpful for both the user and for debugging why the task was expired. Thanks!
2
0
147
4w
i can not run "pgrep" or "ps" in sandbox?
Hi. I'm trying to learn macOS app development. i'm trying to run unix commands: func execute(_ command: String) throws -> String { let process = Process() let pipe = Pipe() process.executableURL = URL(fileURLWithPath: "/bin/bash") process.arguments = ["-c", command] process.standardOutput = pipe // process.standardError try process.run() process.waitUntilExit() guard let data = try pipe.fileHandleForReading.readToEnd() else { throw CommandError.readError } guard let output = String(data: data, encoding: .utf8) else { throw CommandError.invalidData } process.waitUntilExit() guard process.terminationStatus == 0 else { throw CommandError.commandFailed(output) } return output } when try to run "pgrep" in sandbox mode ON, i get: sysmon request failed with error: sysmond service not found error. if i turn it off it works. i don't know what to do. anyone can help me out?
2
0
250
Mar ’25
Incorrect behaviour of task_info() syscall after an unrelated dlclose() call
For some reason, after invoking an unrelated dlclose() call to unload any .dylib that had previously been loaded via dlopen(..., RTLD_NOW), the subsequent call to task_info(mach_task_self(), TASK_DYLD_INFO, ...) syscall returns unexpected structure in dyld_uuid_info image_infos->uuidArray, that, while it seems to represent an array of struct dyld_uuid_info elements, there is only 1 such element (dyld_all_image_infos *infos->uuidArrayCount == 1) and the app crashes when trying to access dyld_uuid_info image->imageLoadAddress->magic, as image->imageLoadAddress doesn't seem to represent a valid struct mach_header structure address (although it looks like a normal pointer within the process address space. What does it point to?). This reproduces on macOS 15.4.1 (24E263) Could you please confirm that this is a bug in the specified OS build, or point to incorrect usage of the task_info() API? Attaching the C++ file that reproduces the issue to this email message It needs to be built on macOS 15.4.1 (24E263) via Xcode or just a command line clang++ compiler. It may crash or return garbage, depending on memory layout, but on this macOS build it doesn’t return a correct feedfacf magic number for the struct mach_header structure. Thank you Feedback Assistant reference: FB18431345 //On `macOS 15.4.1 (24E263)` create a C++ application (for example, in Xcode), with the following contents. Note, that this application should crash on this macOS build. It will not crash, however, if you either: //1. Comment out `dlclose()` call //2. Change the order of the `performDlOpenDlClose()` and `performTaskInfoSyscall()` functions calls (first performTaskInfoSyscall() then performDlOpenDlClose()). #include <iostream> #include <dlfcn.h> #include <mach/mach.h> #include <mach-o/dyld_images.h> #include <mach-o/loader.h> void performDlOpenDlClose() { printf("dlopen/dlclose function\n"); printf("Note: please adjust the path below to any real dylib on your system, if the path below doesn't exist!\n"); std::string path = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libswiftDemangle.dylib"; printf("Dylib to open: %s\n", path.c_str()); void* handle = ::dlopen(path.c_str(), RTLD_NOW); if(handle) { ::dlclose(handle); } else { printf("Error: %s\n", dlerror()); } } void performTaskInfoSyscall() { printf("Making a task_info() syscall\n"); printf("\033[34mSource File: %s\033[0m\n", __FILE__); task_t task = mach_task_self(); struct task_dyld_info dyld_info; mach_msg_type_number_t size = TASK_DYLD_INFO_COUNT; kern_return_t kr = task_info(task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &size); if (kr != KERN_SUCCESS) { fprintf(stderr, "task_info failed: %s\n", mach_error_string(kr)); } const struct dyld_all_image_infos* infos = (const struct dyld_all_image_infos*)dyld_info.all_image_info_addr; printf("version: %d, infos->infoArrayCount: %d\n", infos->version, infos->infoArrayCount); for(uint32_t i=0; i<infos->infoArrayCount; i++) { dyld_image_info image = infos->infoArray[i]; const struct mach_header* header = image.imageLoadAddress; printf("%d ", i); printf("%p ", (void*)image.imageLoadAddress); printf("(%x) ", header->magic); printf("%s\n", image.imageFilePath); fflush(stdout); } printf("\n\n"); printf("infos->uuidArrayCount: %lu\n", infos->uuidArrayCount); for(uint32_t i=0; i<infos->uuidArrayCount; i++) { dyld_uuid_info image = infos->uuidArray[i]; const struct mach_header* header = image.imageLoadAddress; printf("%d ", i); printf("%p ", (void*)image.imageLoadAddress); printf("(%x)\n", header->magic); fflush(stdout); } printf("task_info() syscall result processing is completed\n\n"); } int main(int argc, const char * argv[]) { performDlOpenDlClose(); performTaskInfoSyscall(); return 0; }
4
0
160
Jun ’25
macOS 14 XPC vs Foundation XPC
I'm looking into a newer XPC API available starting with macOS 14. Although it's declared as a low-level API I can't figure it how to specify code signing requirement using XPCListener and XPCSession. How do I connect it with xpc_listener_set_peer_code_signing_requirement and xpc_connection_set_peer_code_signing_requirement which require xpc_listener_t and xpc_connection_t respectively? Foundation XPC is declared as a high-level API and provides easy ways to specify code signing requirements on both ends of xpc. I'm confused with all these XPC APIs and their future: Newer really high-level XPCListener and XPCSession API (in low-level framework???) Low-level xpc_listener_t & xpc_connection_t -like API. Is it being replaced by newer XPCListener and XPCSession? How is it related to High-level Foundation XPC? Are NSXPCListener and NSXPCConnection going to be deprecated and replaced by XPCListener and XPCSession??
2
0
754
Aug ’25
utmpx reports several session for the same user
Hello, My app (daemon) time to time need to know list of GUI login sessions. According to the recommendation, I am using getutxent(). https://developer.apple.com/library/archive/qa/qa1133/_index.html However, I have faced with unclear behaviour in case of running "Migration Assistant". It can be re-created without my app. Steps to recreate: login as 'user #1' start "Migration Assistant" quit "Migration Assistant" new login prompt will be opened login as 'user #2' In spite the session of 'user #1' is closed, the command line tool "who", which gathers information from /var/run/utmpx, reports opened sessions of 'user #1'. Is it bug or feature? Thank you in advance!
7
0
213
Jul ’25
DispatchSerialQueue minimum OS support
Hi Team, We intend to create a custom serial dispatch queue targetting a global queue. let serialQueue = DispatchQueue(label: "corecomm.tallyworld.serial", target: DispatchQueue.global(qos: .default)) The documentation for DispatchQueue init does not show any minimum OS versions. BUT DispatchSerialQueue init does show iOS 17.0+ iPadOS 17.0+ Mac Catalyst macOS 14.0+ tvOS 17.0+ visionOS watchOS 10.0+. Does that mean - I will not be able to create a custom serial dispatch queue below iOS 17?
3
0
162
Jul ’25
XPC Error: Underlying connection interrupted
Im using the low-level C xpc api <xpc/xpc.h> and i get this error when I run it: Underlying connection interrupted. I know this error stems from the call to xpc_session_send_message_with_reply_sync(session, message, &reply_err);. I have no previous experience with xpc or dispatch and I find the xpc docs very limited and I also found next to no code examples online. Can somebody take a look at my code and tell me what I did wrong and how to fix it? Thank you in advance. Main code: #include <stdio.h> #include <xpc/xpc.h> #include <dispatch/dispatch.h> // the context passed to mainf() struct context { char* text; xpc_session_t sess; }; // This is for later implementation and the name is also rudimentary void mainf(void* c) { //char * text = ((struct context*)c)->text; xpc_session_t session = ((struct context*)c)->sess; dispatch_queue_t messageq = dispatch_queue_create("y.ddd.main", DISPATCH_QUEUE_SERIAL); xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(message, "test", "eeeee"); if (session == NULL) { printf("Session is NULL\n"); exit(1); } __block xpc_rich_error_t reply_err = NULL; __block xpc_object_t reply; dispatch_sync(messageq, ^{ reply = xpc_session_send_message_with_reply_sync(session, message, &reply_err); if (reply_err != NULL) printf("Reply Error: %s\n", xpc_rich_error_copy_description(reply_err)); }); if (reply != NULL) printf("Reply: %s\n", xpc_dictionary_get_string(reply, "test")); else printf("Reply is NULL\n"); } int main(int argc, char* argv[]) { // Create seperate queue for mainf() dispatch_queue_t mainq = dispatch_queue_create("y.ddd.main", DISPATCH_QUEUE_CONCURRENT); dispatch_queue_t xpcq = dispatch_queue_create("y.ddd.xpc", NULL); // Create the context being sent to mainf struct context* c = malloc(sizeof(struct context)); c->text = malloc(sizeof("Hello")); strcpy(c->text, "Hello"); xpc_rich_error_t sess_err = NULL; xpc_session_t session = xpc_session_create_xpc_service("y.getFilec", xpcq, XPC_SESSION_CREATE_INACTIVE, &sess_err); if (sess_err != NULL) { printf("Session Create Error: %s\n", xpc_rich_error_copy_description(sess_err)); xpc_release(sess_err); exit(1); } xpc_release(sess_err); xpc_session_set_incoming_message_handler(session, ^(xpc_object_t message) { printf("message recieved\n"); }); c->sess = session; xpc_rich_error_t sess_ac_err = NULL; xpc_session_activate(session, &sess_ac_err); if (sess_err != NULL) { printf("Session Activate Error: %s\n", xpc_rich_error_copy_description(sess_ac_err)); xpc_release(sess_ac_err); exit(1); } xpc_release(sess_ac_err); xpc_retain(session); dispatch_async_f(mainq, (void*)c, mainf); xpc_release(session); dispatch_main(); } XPC Service code: #include <stdio.h> #include <xpc/xpc.h> #include <dispatch/dispatch.h> int main(void) { xpc_rich_error_t lis_err = NULL; xpc_listener_t listener = xpc_listener_create("y.getFilec", NULL, XPC_LISTENER_CREATE_INACTIVE, ^(xpc_session_t sess){ printf("Incoming Session: %s\n", xpc_session_copy_description(sess)); xpc_session_set_incoming_message_handler(sess, ^(xpc_object_t mess) { xpc_object_t repl = xpc_dictionary_create_empty(); xpc_dictionary_set_string(repl, "test", "test"); xpc_rich_error_t send_repl_err = xpc_session_send_message(sess, repl); if (send_repl_err != NULL) printf("Send Reply Error: %s\n", xpc_rich_error_copy_description(send_repl_err)); }); xpc_rich_error_t sess_ac_err = NULL; xpc_session_activate(sess, &sess_ac_err); if (sess_ac_err != NULL) printf("Session Activate: %s\n", xpc_rich_error_copy_description(sess_ac_err)); }, &lis_err); if (lis_err != NULL) { printf("Listener Error: %s\n", xpc_rich_error_copy_description(lis_err)); xpc_release(lis_err); } xpc_rich_error_t lis_ac_err = NULL; xpc_listener_activate(listener, &lis_ac_err); if (lis_ac_err != NULL) { printf("Listener Activate Error: %s\n", xpc_rich_error_copy_description(lis_ac_err)); xpc_release(lis_ac_err); } dispatch_main(); }
1
0
365
Mar ’25
How to debug or ensure single resume calls for continuations at compile time or with tools like Instruments?
When using the continuation API, we're required to call resume exactly once. While withCheckedContinuation helps catch runtime issues during debugging, I'm looking for ways to catch such errors at compile time or through tools like Instruments. Is there any tool or technique that can help enforce or detect this requirement more strictly than runtime checks? Or would creating custom abstractions around Continuation be the only option to ensure safety? Any suggestions or best practices are appreciated.
2
0
445
Jan ’25
Background Audio Recording
I have an app that uses background audio recording. From what others say, I have enabled the audio background mode to keep the audio session active, and this worked. But when submitting the app to the app store, the app was rejected because the audio background mode is only supposed to be used for audio playback. How do I create this background mode while following Apple's guidelines?
4
0
180
5d
iOS Team Provisioning Profile” Missing UIBackgroundModes Entitlement
I’m trying to enable Background Modes (specifically for audio, background fetch, remote notifications) in my iOS SwiftUI app, but I’m getting this error: Provisioning profile “iOS Team Provisioning Profile: [my app]” doesn’t include the UIBackgroundModes entitlement. On the developer website when I make the provision profile It doesnt give me the option to allow background modes. I added it to the sign in capabilities seccion in X code and matched the bundle ID to the provision profile and certificate etc but it still runs this error because the provision profile doesnt have the entitlements..
3
0
301
Jul ’25
ExtensionKit & ExtensionFoundation process lifecycle
An XPC service’s process has a system-managed lifecycle: the process is launched on-demand when another process tries to connect to it, and the system can decide to kill it when system resources are low. XPC services can tell the system when they shouldn’t be killed using xpc_transaction_begin/end. Do extensions created with ExtensionFoundation and/or ExtensionKit have the same behavior?
1
0
170
Jul ’25