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

Memory visibility issue regards to shared data with Dispatch Queue
I’m working with apple dispatch queue in C with the following design: multiple dispatch queues enqueue tasks into a shared context, and a dedicated dispatch queue (let’s call it dispatch queue A) processes these tasks. However, it seems this design has a memory visibility issue. Here’s a simplified version of my setup: I have a shared_context struct that holds: task_lis: a list that stores tasks to be prioritized and run — this list is only modified/processed by dispatch queue A (a serially dispatch queue), so I don't lock around it. cross_thread_tasks: a list that other queues push tasks into, protected by a lock. Other dispatch queues call a function schedule_task that locks and appends a new task to cross_thread_tasks call dispatch_after_f() to schedule a process_task() on dispatch queue A process_task() that processes the task_list and is repeatedly scheduled on dispatch queue A : Swaps cross_thread_tasks into a local list (with locking). Pushes the tasks into task_list. Runs tasks from task_list. Reschedules itself via dispatch_after_f(). Problem: Sometimes the tasks pushed from other threads don’t seem to show up in task_list when process_task() runs. The task_list appears to be missing them, as if the cross-thread tasks aren’t visible. However, if the process_task() is dispatched from the same thread the tasks originate, everything works fine. It seems to be a memory visibility or synchronization issue. Since I only lock around cross_thread_tasks, could it be that changes to task_list (even though modified on dispatch queue A only) are not being properly synchronized or visible across threads? My questions What’s the best practice to ensure shared context is consistently visible across threads when using dispatch queues? Is it mandatory to lock around all tasks? I would love to minimize/avoid lock if possible. Any guidance, debugging tips, or architectural suggestions would be appreciated! =============================== And here is pseudocode of my setup if it helps: struct shared_data { struct linked_list* task_list; } struct shared_context { struct shared_data *data; struct linked_list* cross_thread_tasks; struct thread_mutex* lock; // lock is used to protect cross_thread_tasks } static void s_process_task(void* shared_context){ struct linked_list* local_tasks; // lock and swap the cross_thread_tasks into a local linked list lock(shared_context->lock) swap(shared_context->cross_thread_tasks, local_tasks) unlock(shared_context->lock) // I didnt use lock to protect `shared_context->data` as they are only touched within dispatch queue A in this function. for (task : local_tasks) { linked_list_push(shared_context->data->task_list) } // If the `process_task()` block is dispatched from `schedule_task()` where the task is created, the `shared_context` will be able to access the task properly otherwise not. for (task : shared_context->data->task_list) { run_task_if_timestamp_is_now(task) } timestamp = get_next_timestamp(shared_context->data->task_list) dispatch_after_f(timestamp, dispatch_queueA, shared_context, process_task); } // On dispatch queue B static void schedule_task(struct task* task, void* shared_context) { lock(shared_context->lock) push(shared_context->cross_thread_tasks, task) unlock(shared_context->lock) timestamp = get_timestamp(task) // we only dispatch the task if the timestamp < 1 second. We did this to avoid the dispatch queue schedule the task too far ahead and prevent the shutdown process. Therefore, not all task will be dispatched from the thread it created. if(timestamp < 1 second) dispatch_after_f(timestamp, dispatch_queueA, shared_context, process_task); }
3
0
125
May ’25
Cleanup LaunchAgents after development
I have been playing with application bundled LaunchAgents: I downloaded Apple sample code, Run the sample code as is, Tweaked the sample code a lot and changed the LaunchAgents IDs and Mach ports IDs, Created new projects with the learnings, etc. After deleting all the Xcode projects and related project products and rebooting my machine several times, I noticed the LaunchAgent are still hanging around in launchctl. If I write launchctl print-disabled gui/$UID (or user/$UID) I can see all my testing service-ids: disabled services = { "com.xpc.example.agent" => disabled "io.dehesa.apple.app.agent" => disabled "io.dehesa.sample.app.agent" => disabled "io.dehesa.example.agent" => disabled "io.dehesa.swift.xpc.updater" => disabled "io.dehesa.swift.agent" => disabled } (there are more service-ids in that list, but I removed them for brevity purposes). I can enable or disable them with launchctl enable/disable service-target, but I cannot really do anything else because their app bundle and therefore PLIST definition are not there anymore. How can I completely remove them from my system? More worryingly, I noticed that if I try to create new projects with bundled LaunchAgents and try to reuse one of those service-ids, then the LaunchAgent will refuse to run (when it was running ok previously). The calls to SMAppService APIs such .agent(plistName:) and register() would work, though.
3
0
144
May ’25
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
348
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 &lt;private&gt;: Error Domain=NSCocoaErrorDomain Code=4099 UserInfo={NSDebugDescription=&lt;private&gt;} Automatically retrying getting container proxy due to error for &lt;private&gt;: Error Domain=NSCocoaErrorDomain Code=4099 UserInfo={NSDebugDescription=&lt;private&gt;} XPC connection interrupted for &lt;private&gt; 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
179
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
99
May ’25
Getting Progress from long running process
I have been working on updating an old app that makes extensive use of Objective-C's NSTask. Now using Process in Swift, I'm trying to gather updates as the process runs, using readabilityHandler and availableData. However, my process tends to exit before all data has been read. I found this post entitled "Running a Child Process with Standard Input and Output" but it doesn't seem to address gathering output from long-running tasks. Is there a straightforward way to gather ongoing output from a long running task without it prematurely exiting?
10
0
192
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
169
May ’25
Cross process URL bookmark
I am developing a background application that acts as a metadata server under MacOS written in Swift. Sandboxed clients prompt the user to select URLs which are passed to the server as security scoped bookmarks via an App Group and the metadata will be passed back. I don't want the I/O overhead of passing the complete image file data to the server. All the variations I have tried of creating security scoped bookmarks in the client and reading them from the server fail with error messages such as "The file couldn’t be opened because it isn’t in the correct format." Can anyone guide me in the right direction or is this just not possible?
10
0
227
Jun ’25
How to prevent the main app from being terminated by the system during long - term system - level recording
After logging in to the main App, turn on screen recording, then switch to the interface of another App to perform operations. After about ten-odd minutes, when returning to the main App, it was found that the app was forcefully quit by the system, and subsequent operations could not be carried out.
1
0
129
May ’25
Background App Refresh
Hi, I have a couple questions about background app refresh. First, is the function RefreshAppContentsOperation() where to implement code that needs to be run in the background? Second, despite importing BackgroundTasks, I am getting the error "cannot find operationQueue in scope". What can I do to resolve that? Thank you. func scheduleAppRefresh() { let request = BGAppRefreshTaskRequest(identifier: "peaceofmindmentalhealth.RoutineRefresh") // Fetch no earlier than 15 minutes from now. request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) do { try BGTaskScheduler.shared.submit(request) } catch { print("Could not schedule app refresh: \(error)") } } func handleAppRefresh(task: BGAppRefreshTask) { // Schedule a new refresh task. scheduleAppRefresh() // Create an operation that performs the main part of the background task. let operation = RefreshAppContentsOperation() // Provide the background task with an expiration handler that cancels the operation. task.expirationHandler = { operation.cancel() } // Inform the system that the background task is complete // when the operation completes. operation.completionBlock = { task.setTaskCompleted(success: !operation.isCancelled) } // Start the operation. operationQueue.addOperation(operation) } func RefreshAppContentsOperation() -> Operation { }
27
0
707
Jan ’26
Bundled app error with Electron app on Mac App Store
Hi, I built an Electron app that uses puppeteer-cluster to open a bundled version of Chrome. Everything works before packaging/signing with electron builder. Transporter does not report any issues and the app opens in TestFlight. the Chrome.app is signed separately before running builder hardenedRuntime = false However, a permission error occurs when cluster attempts to launch Chrome: Error: Unable to launch browser, error message: Failed to launch the browser process! [0601/152740.225314:ERROR:bootstrap.cc(65)] bootstrap_check_in org.chromium.crashpad.child_port_handshake.9915.63117.BUEXLMXFWPLCEONM: Permission denied (1100) [0601/152740.226091:ERROR:file_io.cc(94)] ReadExactly: expected 4, observed 0 [0601/152740.229808:ERROR:bootstrap.cc(65)] bootstrap_check_in org.chromium.crashpad.child_port_handshake.9913.63115.VVKELOQUCWUYPFMQ: Permission denied (1100) [0601/152740.230244:ERROR:file_io.cc(94)] ReadExactly: expected 4, observed 0 [9911:45571:0601/152740.506968:ERROR:named_platform_channel_mac.cc(44)] bootstrap_check_in com.google.chrome.for.testing.apps.52995c87946bbcc94fc9a27df1478a13: Permission denied (1100) [9911:62467:0601/152740.507564:FATAL:mach_port_rendezvous.cc(281)] Check failed: kr == KERN_SUCCESS. bootstrap_check_in com.google.chrome.for.testing.MachPortRendezvousServer.9911: Permission denied (1100) at Cluster.<anonymous> (/Applications/MyApp.app/Contents/Resources/app.asar/node_modules/puppeteer-cluster/dist/Cluster.js:119:23) at Generator.throw (<anonymous>) at rejected (/Applications/MyApp.app/Contents/Resources/app.asar/node_modules/puppeteer-cluster/dist/Cluster.js:6:65) at process.processTicksAndRejections (node:internal/process/task_queues:105:5) I'm wondering if it's an issue with entitlements, or something more. The entitlements.mas.plist (aside from identifiers): com.apple.security.app-sandbox com.apple.security.cs.allow-jit com.apple.security.cs.allow-unsigned-executable-memory com.apple.security.cs.allow-dyld-environment-variables com.apple.security.network.client com.apple.security.network.server com.apple.security.files.user-selected.read-write com.apple.security.cs.disable-executable-page-protection com.apple.security.files.user-selected.executable I've spent many hours searching for a solution. Any help or insight would be greatly appreciated.
5
0
166
Jun ’25
How can I bundle resources along with my launch agent?
I have an app which contains a bundled launch agent that I register using SMAppService.agent(plistName:). I’ve packaged the launch agent executable in the typical Mac app bundle structure so I can embed a framework in it. So, the launch agent lives in Contents/SharedSupport/MyLaunchAgent.app/Contents/MacOS/MyLaunchAgent. However, I suspect this approach might be falling afoul of the scheduler, since the taskinfo tool reports my launch agent has a requested & effective role of TASK_DEFAULT_APPLICATION (PRIO_DARWIN_ROLE_UI), rather than the TASK_UNSPECIFIED (PRIO_DARWIN_ROLE_DEFAULT) value I see with system daemons. I tried setting the LSUIElement Info.plist key of my launch agent to YES, but this seems to have had no effect. What’s the recommended approach here?
7
0
218
Jun ’25
How to capture stderr from a macOS GUI app (UIKit/AppKit) when launched via open or Finder?
For a macOS GUI application (with a UIKit or AppKit entry point), I want to reliably capture diagnostic logs sent to stderr — especially useful when the app is launched from a terminal script or runs in the background, and traditional GUI elements (like alert dialogs) may not be viable. This is to log startup failures or even success messages for later inspection. However, when the app is launched via open MyApp.app, stderr redirection like open MyApp.app 2> log.txt does not capture any output — the file is created, but remains empty. The only way I can capture stderr reliably is by bypassing the bundle and directly launching the binary inside with ./MyApp.app/Contents/MacOS/MyApp 2> ~/log.txt This logs as expected, but is not the user-friendly or typical way to launch apps on macOS. Double-clicking the app in Finder also does not show any stderr output. Is there any recommended or supported way to redirect or access stderr output when launching a .app bundle via open, or any best practice for logging critical failures from a GUI app when terminal output isn't visible?
5
0
215
Jun ’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-&gt;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-&gt;uuidArrayCount == 1) and the app crashes when trying to access dyld_uuid_info image-&gt;imageLoadAddress-&gt;magic, as image-&gt;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 &lt;iostream&gt; #include &lt;dlfcn.h&gt; #include &lt;mach/mach.h&gt; #include &lt;mach-o/dyld_images.h&gt; #include &lt;mach-o/loader.h&gt; 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)&amp;dyld_info, &amp;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-&gt;infoArrayCount: %d\n", infos-&gt;version, infos-&gt;infoArrayCount); for(uint32_t i=0; i&lt;infos-&gt;infoArrayCount; i++) { dyld_image_info image = infos-&gt;infoArray[i]; const struct mach_header* header = image.imageLoadAddress; printf("%d ", i); printf("%p ", (void*)image.imageLoadAddress); printf("(%x) ", header-&gt;magic); printf("%s\n", image.imageFilePath); fflush(stdout); } printf("\n\n"); printf("infos-&gt;uuidArrayCount: %lu\n", infos-&gt;uuidArrayCount); for(uint32_t i=0; i&lt;infos-&gt;uuidArrayCount; i++) { dyld_uuid_info image = infos-&gt;uuidArray[i]; const struct mach_header* header = image.imageLoadAddress; printf("%d ", i); printf("%p ", (void*)image.imageLoadAddress); printf("(%x)\n", header-&gt;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
162
Jun ’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
218
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
196
Jul ’25
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
309
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
189
Jul ’25
Need to start the Mac application automatically
I am developing the application in Mac. My requirement is to start the application automatically when user login. I have tried adding the plist file in launch agents, But it doesn't achieve my requirement. Please find the code added in the launch agents &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt; &lt;plist version="1.0"&gt; &lt;dict&gt; &lt;key&gt;Label&lt;/key&gt; &lt;string&gt;com.sftk.secure&lt;/string&gt; &lt;key&gt;ProgramArguments&lt;/key&gt; &lt;array&gt; &lt;string&gt;/Applications/Testing.app/Contents/MacOS/Testing&lt;/string&gt; &lt;/array&gt; &lt;key&gt;RunAtLoad&lt;/key&gt; &lt;true/&gt; &lt;key&gt;KeepAlive&lt;/key&gt; &lt;false/&gt; &lt;/dict&gt; &lt;/plist&gt; I have tried by adding manually in the setting, but it was opened sometimes and closed suddenly. On open manually it works. Please provide a solution to start the application automatically on system starts
1
0
939
Jul ’25
Running external binaries from Swift Package (TTS engine): Operation not permitted from Xcode app
Hi everyone, We’re developing a macOS SwiftUI app that uses a local Swift Package (CasSherpaCore) to invoke an external compiled binary (sherpa-onnx-offline-tts) for text-to-speech synthesis using system calls. The package works flawlessly when tested from terminal or via a lightweight test C program. However, when we invoke it from a SwiftUI app (even with Full Disk Access granted to Xcode and Terminal), we consistently get the error: sh: /Users/xxxxxxxxxxx/SherpaONNX/sherpa-onnx/build/bin/sherpa-onnx-offline-tts: Operation not permitted We’ve tried: Granting Full Disk Access to Xcode and Terminal. Removing the quarantine flag with xattr -d com.apple.quarantine. Setting executable permission via chmod +x. Using both system() and Process in C and Swift contexts. Testing within a Swift Package that’s integrated into the app as a local dependency. Running the command manually from terminal (works perfectly). It appears that macOS (or Xcode’s runtime sandbox) is restricting execution of binaries from certain locations or contexts when launched via system() inside the app. Questions: Is there a specific entitlement or configuration that allows execution of local binaries from a SwiftUI macOS app? Is this related to System Integrity Protection (SIP) or a hardened runtime limitation? Are there best practices or alternative approaches to safely execute local TTS binaries from within a Swift app? Any help would be deeply appreciated. This is a core feature in our project and we’re stuck at this point. Thank you so much in advance!
1
0
98
Jul ’25