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

Why is xpc_connection_set_peer_code_signing_requirement() closing the connection instead of returning XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT?
I'm using libxpc in a C server and Swift client. I set up a code-signing requirement in the server using xpc_connection_set_peer_code_signing_requirement(). However, when the client doesn't meet the requirement, the server just closes the connection, and I get XPC_ERROR_CONNECTION_INTERRUPTED on the client side instead of XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT, making debugging harder. What I want: To receive XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT on the client when code-signing fails, for better debugging. What I’ve tried: Using xpc_connection_set_peer_code_signing_requirement(), but it causes the connection to be dropped immediately. Questions: Why does the server close the connection without sending the expected error? How can I receive the correct error on the client side? Are there any other methods for debugging code-signing failures with libxpc? Thanks for any insights!
1
0
472
Feb ’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
166
Jul ’25
Is background processing even possible?
Hello, aspiring programmer here. I am developing a StepCounter APP, which keeps track of how many steps I have taken and sends to an MQTT server. I am trying to make this happen even while the app is not in focus, but so far I have not been able to get this working. First tried with silent background music, which seemed pretty inconsistent and inpractical, since I usually play youtube videoes while walking, making the app stop with its silent audio. Then tried GPS, which didnt really do anything (could be implementation problem). Has anyone made background processing work for their apps?
1
0
111
Mar ’25
How to Get Client Process Owner in an XPC Server
I'm working on an XPC server and need to determine the owner of the client process that connects to it. Specifically, I'd like to retrieve details such as the fully qualified user name or other identifying information from the XPC client connection.I'm considering using xpc_connection_get_pid() to get the client’s process ID, but I’m unsure of the best way to map this to the user who owns the process. Is there a recommended API or approach to capture this information securely?
1
3
218
Mar ’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
349
Mar ’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
86
Jul ’25
dispatch_main and main thread local variables
Hello, We're seeing some strange crashes and noticed the following. It's unclear if related or not. The contract for xpc_main, which internally calls dispatch_main, is This function never returns. and they are appropriately peppered with __attribute__((__noreturn__)). Documentation states: This function “parks” the main thread and waits for blocks to be submitted to the main queue. However, internally, dispatch_main calls pthread_exit. pthread_exit's documentation states that: After a thread has terminated, the result of access to local (auto) variables of the thread is undefined. Thus, references to local variables of the exiting thread should not be used for the pthread_exit() value_ptr parameter value. I'd say the two contracts of This function never returns. and thread exiting with its storage released are diametrically opposed and can create nuanced issues. Consider the following code: struct asd { int a; }; struct asd* ptr; void fff(void* ctx) { while(true) { printf("%d\n", ptr->a); ptr->a = (ptr->a + 1); usleep(100000); } } int main(int argc, const char * argv[]) { struct asd zxc; zxc.a = 1; ptr = &zxc; dispatch_async_f(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), NULL, fff); dispatch_main(); return 0; } This is a gross over-simplification of the code we have, but in the same "spirit". We have a C++ object that is created on the stack and exposes one of its members as a global pointer, with the assumption that it would never release. What I understand from This function never returns is that the calling thread remains dormant and its stack remains alive. What I understand from pthread_exit is that the thread is killed (this is verified with a debugger attached) and its stack storage is released. Another thing that is throwing me off is that no sanitizer that is provided by clang/Xcode catches this issue. I don't see any special handling of the internal pthread_t in libdispatch to keep the stack storage alive. Our code is more complex, but can be solved by allocating the initial object on the heap, rather than on the stack. But still I would like to understand if this is the expected behavior. Perhaps my preconception of __attribute__((__noreturn__)) is wrong, and accessing stack variables post call to a __attribute__((__noreturn__)) function is UB? Thanks
1
0
122
Jul ’25
XPC - performance/load testing
I have an XPC server running on macOS and want to perform comprehensive performance and load testing to evaluate its efficiency, responsiveness, and scalability. Specifically, I need to measure factors such as request latency, throughput, and how well it handles concurrent connections under different load conditions. What are the best tools, frameworks, or methodologies for testing an XPC service? Additionally, are there any best practices for simulating real-world usage scenarios and identifying potential bottlenecks?
1
1
129
Apr ’25
Issue with launchd Job Not Running – "Bootstrap failed: 5: Input/output error"
Purpose I want to use launchd to run a shell script asynchronously every minute, but I'm encountering an issue where the job does not run, and I receive the error "Bootstrap failed: 5: Input/output error". I need help identifying the cause of this issue and how to configure launchd correctly. What I've done Created the shell script (test_ls_save.sh) The script is designed to list the contents of the desktop and save the output to a specified directory. #!/bin/bash DATE=$(date +%Y-%m-%d_%H-%M-%S) SAVE_DIR=/Users/test/Desktop/personal/log_gather FILE_NAME="ls_output_$DATE.log" ls ~/Desktop &gt; "$SAVE_DIR/$FILE_NAME" echo "ls output saved to $SAVE_DIR/$FILE_NAME" File permissions (ls -l output): -rwxr-xr-x 1 test staff 1234 Feb 17 10:00 /Users/test/Desktop/personal/log_gather/exec/test_ls_save.sh Created the launchd plist file (com.test.logTest.plist) The plist file is configured to execute the shell script every minute. &lt;key&gt;Label&lt;/key&gt; &lt;string&gt;com.test.logTest&lt;/string&gt; &lt;key&gt;ProgramArguments&lt;/key&gt; &lt;array&gt; &lt;string&gt;/bin/bash&lt;/string&gt; &lt;string&gt;-c&lt;/string&gt; /Users/test/Desktop/personal/log_gather/exec/test_ls_save.sh &lt;/array&gt; &lt;key&gt;StartInterval&lt;/key&gt; &lt;integer&gt;60&lt;/integer&gt; &lt;!-- Run every minute --&gt; File permissions (ls -l output): -rwxr-xr-x 1 test staff 512 Feb 17 10:00 /Users/test/Library/LaunchAgents/com.test.logTest.plist Ran the job with launchctl I used the following command to load the plist file into launchd: sudo launchctl bootstrap gui/$(id -u) /Users/test/Library/LaunchAgents/com.test.logTest.plist pc spec MacBook Pro Apple M1 16 GB RAM macOS 15.3 (Build 24D60) what I know The configuration has been set, but the launchd job is not running every minute as expected. I don't believe there is a mistake with the path. When I check the job using launchctl list, the job does not appear in the list. I don't know where the error log files are supposed to be. I checked /var/log/system.log, but there are no error logs. The .sh file runs fine by itself, but it cannot be executed via launchctl. Want to ask What could be the cause of the launchd job not running as expected? Also, is there a way to check where the logs are being output? If there is an error in the plist file configuration, which part should be modified? Specifically, what improvements should be made regarding environment variables and path settings? If my information is not enough, please tell me what is not enough!
1
0
613
Feb ’25
Effect of app nap of Timer
I'm developing a macOS application that tracks the duration of a user's session using a timer, which is displayed both in the main window and in an menu bar extra view. I have a couple of questions regarding the timer's behavior: What happens to the timer if the user closes the application's window (causing the app to become inactive) but does not fully quit it? Does the timer continue to run, pause, or behave in some other way? Will the app nap feature stop the timer when app is in-active state? When the application is inactive and the system is either in sleep mode or locked, does the timer’s tolerance get affected? In other words, will the timer fire with any additional delay compared to its scheduled time under these conditions?
1
0
76
Mar ’25
Some questions about how to use the Background Assets capability on iOS
Regarding the Background Assets capability on iOS: In the install scenario, resources defined as the "install" type are incorporated into the App Store download progress. Do resources of the "update" type in the update scenario also get incorporated into the App Store download progress in the same way? If an exception occurs during the download of install-type resources and the download cannot proceed further, will the system no longer actively block users from launching the app and instead enable the launch button? Currently, if a user has enabled automatic updates on their device, after the app is updated and released on the App Store, will the Background Assets download start immediately once the automatic update completes? Or does Background Assets have its own built-in scheduling logic that prevents it from running concurrently with the automatic update?
1
0
59
2w
Did GCD change in macOS 26
Some users of my Mac app are complaining of redrawing delays. Based on what I see in logs, my GCD timer event handlers are not being run in a timely manner although the runloop is still pumping events: sometimes 500ms pass before a 15ms timer runs. During this time, many keypresses are routed through -[NSApplication sendEvent:], which is how I know it's not locked up in synchronous code. This issue has not been reported in older versions of macOS. I start the timer like this: _gcdUpdateTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); dispatch_source_set_timer(_gcdUpdateTimer, dispatch_time(DISPATCH_TIME_NOW, period * NSEC_PER_SEC), period * NSEC_PER_SEC, 0.0005 * NSEC_PER_SEC); dispatch_source_set_event_handler(_gcdUpdateTimer, ^{ …redraw… });
1
0
104
Sep ’25
Background refresh or processing app
I am writing an app which mainly is used to update data used by other apps on the device. After the user initializes some values in the app, they almost never have to return to it (occasionally to add a "friend"). The app needs to run a background task at least daily, however, without the user's intervention (or even awareness, once they've given permission). My understanding of background refresh tasks is that if the user doesn't activate the app in the foreground periodically, the scheduled background tasks may never run. If this is true, do I want to use a background processing task instead, or is there a better solution (or have I misunderstood entirely)?
1
0
399
Jan ’25
How to detect or opt out of iOS app prewarming?
Hi, We are running into issues with iOS app prewarming, where the system launches our app before the user has entered their passcode. In our case, the app stores flags, counters, and session data in UserDefaults and the Keychain. During prewarm launches: UserDefaults only returns default values (nil, 0, false). We have no way of knowing whether this information is valid or just a placeholder caused by prewarming. Keychain items with kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly are inaccessible, which can lead to broken business logic (the app can assume no session exists). No special launch options or environment variables appear to be set. We can reproduce this 100% of the time by starting a Live Activity in the app before reboot. Here’s an example of the workaround we tried, following older recommendations: __attribute__((constructor)) static void ModuleInitializer(void) { char* isPrewarm = getenv("ActivePrewarm"); if (isPrewarm != NULL && isPrewarm[0] == '1') { exit(0); // prevent prewarm launch from proceeding } } On iOS 16+, the ActivePrewarm environment variable doesn’t seem to exist anymore (though older docs and SDKs such as Sentry reference it). We also tried listening for UIApplication.protectedDataDidBecomeAvailableNotification, but this is not specific to prewarming (it also fires when the device gets unlocked) and can cause watchdog termination if we delay work too long. Questions: Is there a supported way to opt out of app prewarming? What is the correct way to detect when an app is being prewarmed? Is the ActivePrewarm environment variable still supported in iOS 16+? Ideally, the UserDefaults API itself should indicate whether it is returning valid stored values or defaults due to the app being launched in a prewarm session. We understand opting out may impact performance, but data security and integrity are our priority. Any guidance would be greatly appreciated.
1
0
170
Oct ’25
SMAppService daemon not running
My app uses SMAppService to register a privileged helper, the helper registers without errors, and can be seen in System Settings. I can get a connection to the service and a remote object proxy, but the helper process cannot be found in Activity Monitor and the calls to the proxy functions seem to always fail without showing any specific errors. What could be causing this situation?
1
0
243
Jul ’25
When using SMAppService to register a daemon, is it possible to let the authorization dialog show on behalf of my application? e.g.: showing the app name, custom icon and prompt, etc..
My app is for personal use currently, so distribution won't be a problem. It registers a privileged helper using SMAppService, and I was wondering whether there is a way to customize the authorization dialog that the system presents to the user.
1
0
132
Jul ’25
Does BGAppRefreshTask require an internet connection?
Basically the title. I am trying to implement a local notification to trigger, regardless of internet connection, around 3-5pm if a certain array in the app is not empty to get the user to sync unsaved work with the cloud. I wanted to used the BGAppRefreshTask as I saw it was lightweight and quick for just posting a banner notification but after inspecting it in the console, it looks like it needs internet connection to trigger. Is this the case or am I doing something wrong? Should I be using the BGProcessingTask instead?
1
0
92
Jul ’25