Processes & Concurrency

RSS for tag

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

Concurrency Documentation

Post

Replies

Boosts

Views

Activity

How do you allow an XPC service to create a new file based on an NSURL that the user selected from an NSSavePanel?
How do you send an NSURL representing a new file, as returned from an NSSavePanel, to an XPC service such that the service is granted permission to create the file? I can successfully pass an NSURL to the XPC process if the NSURL represents an existing file. This is documented in Apple's Documentation: Share file access between processes with URL bookmarks This involves creating bookmark date while passing 0 in as the options. However, if you try to create bookmark data for an NSURL that represents a file that is not yet created, you do not get any bookmark data back and an error is returned instead: Error Domain=NSCocoaErrorDomain Code=260 "The file couldn’t be opened because it doesn’t exist." Simply passing the file path to the XPC process, by way of: xpc_dictionary_set_string(message, "file_path", url.fileSystemRepresentation); Does not grant the XPC create/write permissions. Is there an API or trick I'm missing? Note that the user should be allowed to save and create new files anywhere of their choosing, thus restricting URLs to only those within a group or container shared between the app and service isn't really viable. Using the latest of everything on macOS with the xpc_session API...
1
0
593
Jun ’24
Can helper application launch XPCService that embedded in its bundle?
Hi, I have an application, it has a helper application in its bundle. After the application starts to run, it will launch the helper application process. The helper application process will load a XPCService embedded in its bundle by launchd. But I got an error which is Error Domain=NSOSStatusErrorDomain Code=-10811 "kLSNotAnApplicationErr: Item needs to be an application, but is not" UserInfo={_LSLine=175, _LSFunction=_LSFindBundleWithInfo_NoIOFiltered} How can the helper application launch a XPCService embedded in its bundle? Or the XPCService can only be launched in main application? Thanks
3
0
477
May ’24
identify app modifying screen share
MacBook Pro M1 with an external monitor. For years, the external as Main and the built-in monitor was Extended. After 14.5 update, when a specific user logs on, the built-in monitor "disappears" from Displays and the two monitors show the same desktop. That is as if the external monitor is the only one. If the monitor cable is unplugged, the MacBook boots normally. Plugging in the external monitor following normal boot results in the external becoming Main and built-in Extended. I suspect some launch item install with an app is affecting the display config. I first removed zoom, but no change. There are about 110 apps installed on this machine. How to determine which module or app is doing this? That is, is there a tool or log setting that would note a change in the display settings? I would like to narrow the likely candidates.
0
0
369
May ’24
How to check XPCConnection is REALLY connected
I'm using XPC to do IPC with an agent service. I use NSXPCConnection initWithMachServiceName to create the connection and active it. Then I get the agent service remote object proxy with method remoteObjectProxyWithErrorHandler. But when the agent service unloaded, I can also get the remote proxy without any error. Is there anyway to check XPCConnection really connect to a XPC server?
1
0
521
May ’24
Error 159 - Sandbox restriction when connecting to XPC service
Hello Apple Developer Community, I'm encountering an issue with my macOS application where I'm receiving the following error message: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.FxPlugTestXPC was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.FxPlugTestXPC was invalidated: failed at lookup with error 159 - Sandbox restriction.} This error occurs when my application tries to establish a connection to an XPC service named com.FxPlugTestXPC. It appears to be related to a sandbox restriction, but I'm unsure how to resolve it. I've checked the sandboxing entitlements and ensured that the necessary permissions are in place. However, the issue persists. Has anyone encountered a similar error before? If so, could you please provide guidance on how to troubleshoot and resolve this issue? Any help or insights would be greatly appreciated. Thank you. this is some photos about my entitlements :
16
0
2.7k
Apr ’24
What is the difference between OSAllocatedUnfairLock's withLock and withLockUnchecked functions?
OSAllocatedUnfairLock has two different methods for executing a block of code with the lock held: withLock() and withLockUnchecked(). The only difference between the two is that the former has the closure and return type marked as Sendable. withLockUnchecked() has a comment (that is for reasons I do not understand not visible in the documentation) saying: /// This method does not enforce sendability requirement /// on closure body and its return type. /// The caller of this method is responsible for ensuring references /// to non-sendables from closure uphold the Sendability contract. What I do not understand here is why Sendable conformance would be needed. These function should call this block synchronously in the same context, and return the return value through a normal function return. None of this should require the types to be Sendable. This seems to be supported by this paragraph of the documentation for OSAllocatedUnfairLock: /// This lock must be unlocked from the same thread that locked it. As such, it /// is unsafe to use `lock()` / `unlock()` across an `await` suspension point. /// Instead, use `withLock` to enforce that the lock is only held within /// a synchronous scope. So, why does this Sendable requirement exist, and in practice, if I did want to use withLockUnchecked, how would I "uphold the Sendability contract"? To summarise the question in a more concise way: Is there an example where using withLockUnchecked() would actually cause a problem, and using withLock() instead would catch that problem?
7
0
921
Apr ’24
Non-sendable type ModelContext on MainActor
Hi, just trying to learn how to work with mainActor. I am in a need of analyzing users data with API service one a background. Whenever user saves a post into SwiftData, I need to analyze that posts asynchronously. Here is my current code, which by the way works, but I am getting warning here; actor DatabaseInteractor { let networkInteractor: any NetworkInteractor = NetworkInteractorImpl() func loadUserProfile() async -> String { do { let objects = try await modelContainer.mainContext.fetch(FetchDescriptor<ProfileSwiftData>()) if let profileTest = objects.first?.profile { return profileTest } } catch { } return "" } I get a warning on let objects line. Warning: Non-sendable type 'ModelContext' in implicitly asynchronous access to main actor-isolated property 'mainContext' cannot cross actor boundary
1
0
1.5k
Apr ’24
Callback is not invoked when a closure callback-style call is executed in XPC
I noticed a problem while writing a program using XPC on macOS. When I write it in the form of a closure that receives the result of an XPC call, I can't receive it forever. I add an XPC target in Xcode, the sample code is used in the pass closure format, but can't I use closure passing with XPC? My Environment: Xcode 15.3 macOS 14.4.1 caller (closure version) struct ContentView: View { @State var callbackResult: String = "Waiting…" var body: some View { Form { Section("Run XPC Call with no argument and no return value using callback") { Button("Run…") { callbackResult = "Running…" let service = NSXPCConnection(serviceName: "net.mtgto.example-nsxpc-throws-error.ExampleXpc") service.remoteObjectInterface = NSXPCInterface(with: ExampleXpcProtocol.self) service.activate() guard let proxy = service.remoteObjectProxy as? any ExampleXpcProtocol else { return } defer { service.invalidate() } proxy.performCallback { callbackResult = "Done" } } Text(callbackResult) ... } } } callee (closure version) @objc protocol ExampleXpcProtocol { func performCallback(with reply: @escaping () -> Void) } class ExampleXpc: NSObject, ExampleXpcProtocol { @objc func performCallback(with reply: @escaping () -> Void) { reply() } } I found this problem can be solved by receiving asynchronous using Swift Concurrency. caller (async version) struct ContentView: View { @State var callbackResult: String = "Waiting…" var body: some View { Form { Section("Run XPC Call with no argument and no return value using callback") { Button("Run…") { simpleAsyncResult = "Running…" Task { let service = NSXPCConnection(serviceName: "net.mtgto.example-nsxpc-throws-error.ExampleXpc") service.remoteObjectInterface = NSXPCInterface(with: ExampleXpcProtocol.self) service.activate() guard let proxy = service.remoteObjectProxy as? any ExampleXpcProtocol else { return } defer { service.invalidate() } await proxy.performNothingAsync() simpleAsyncResult = "DONE" } Text(simpleAsyncResult) ... } } } callee (async version) @objc protocol ExampleXpcProtocol { func performNothingAsync() async } class ExampleXpc: NSObject, ExampleXpcProtocol { @objc func performNothingAsync() async {} } To simplify matters, I write source code that omits the arguments and return value, but it is not also invoked by using callback style. All sample codes are available in https://github.com/mtgto/example-nsxpc-throws-error
2
0
662
Apr ’24
Are XPCSession and XPCListener incomplete(ly documented)?
I've been experimenting with the new low-level Swift API for XPC (XPCSession and XPCListener). The ability to send and receive Codable messages is an appealing alternative to making an @objc protocol in order to use NSXPCConnection from Swift — I can easily create an enum type whose cases map onto the protocol's methods. But our current XPC code validates the incoming connection using techniques similar to those described in Quinn's "Apple Recommended" response to the "Validating Signature Of XPC Process" thread. I haven't been able to determine how to do this with XPCListener; neither the documentation nor the Swift interface have yielded any insight. The Creating XPC Services article suggests using Xcode's XPC Service template, which contains this code: let listener = try XPCListener(service: serviceName) { request in request.accept { message in performCalculation(with: message) } } The apparent intent is to inspect the incoming request and decide whether to accept it or reject it, but there aren't any properties on IncomingSessionRequest that would allow the service to make that decision. Ideally, there would be a way to evaluate a code signing requirement, or at least obtain the audit token of the requesting process. (I did notice that a function xpc_listener_set_peer_code_signing_requirement was added in macOS 14.4, but it takes an xpc_listener_t argument and I can't tell whether XPCListener is bridged to that type.) Am I missing something obvious, or is there a gap in the functionality of XPCListener and IncomingSessionRequest?
2
0
618
Apr ’24
Compile XPC service with a different architecture than the client
I'm working on a macOS application that deals with a few external dependencies that can only be compiled for intel (x86_64) but I want the app to run natively on both arm and x86_64. One idea I have been playing with is to move the x86_64 dependencies to an xpc service compiled only as x86_64 and use the service only the intel machine. However, I can't figure out how to setup my project to compile everything at once... Any ideas? Is this even possible? If not, I'm open to suggestions... Thanks
2
0
538
Mar ’24
Handle multiple AsyncThrowingStreams in structured concurrency?
Hello, im currently rewriting my entire network stuff to swift concurrency. I have a Swift Package which contains the NWConnection with my custom framing protocol. So Network framework does not support itself concurrency so I build an api around that. To receive messages I used an AsyncThrowingStream and it works like that: let connection = MyNetworkFramework(host: "example.org") Task { await connection.start() for try await result in connection.receive() { // do something with result } } that's pretty neat and I like it a lot but now things got tricky. in my application I have up to 10 different tcp streams I open up to handle connection stuff. so with my api change every tcp connection runs in it's own task like above and I have no idea how to handle the possible errors from the .receive() func inside the tasks. First my idea was to use a ThrowingTaskGroup for that and I think that will work but biggest problem is that I initially start with let's say 4 tcp connections and I need the ability to add additional ones later if I need them. so it seems not possible to add a Task afterwards to the ThrowingTaskGroup. So what's a good way to handle a case like that? i have an actor which handles everything in it's isolated context and basically I just need let the start func throw if any of the Tasks throw I open up. Here is a basic sample of how it's structured. Thanks Vinz internal actor MultiConnector { internal var count: Int { connections.count } private var connections: [ConnectionsModel] = [] private let host: String private let port: UInt16 private let parameters: NWParameters internal init(host: String, port: UInt16, parameters: NWParameters) { self.host = host self.port = port self.parameters = parameters } internal func start(count: Int) async throws -> Void { guard connections.isEmpty else { return } guard count > .zero else { return } try await sockets(from: count) } internal func cancel() -> Void { guard !connections.isEmpty else { return } for connection in connections { connection.connection.cancel() } connections.removeAll() } internal func sockets(from count: Int) async throws -> Void { while connections.count < count { try await connect() } } } // MARK: - Private API - private extension MultiConnector { private func connect() async throws -> Void { let uuid = UUID(), connection = MyNetworkFramework(host: host, port: port, parameters: parameters) connections.append(.init(id: uuid, connection: connection)) let task = Task { [weak self] in guard let self else { return }; try await stream(connection: connection, id: uuid) } try await connection.start(); await connection.send(message: "Sample Message") // try await task.value <-- this does not work because stream runs infinite until i cancel it (that's expected and intended but it need to handle if the stream throws an error) } private func stream(connection: MyNetworkFramework, id: UUID) async throws -> Void { for try await result in connection.receive() { if case .message(_) = result { await connection.send(message: "Sample Message") } // ... more to handle } } }
3
0
898
Mar ’24
XPC Resources
XPC is the preferred inter-process communication (IPC) mechanism on Apple platforms. XPC has three APIs: The high-level NSXPCConnection API, for Objective-C and Swift The low-level Swift API, introduced with macOS 14 The low-level C API, which, while callable from all languages, works best with C-based languages General: DevForums tag: XPC Creating XPC services documentation NSXPCConnection class documentation Low-level API documentation XPC has extensive man pages — For the low-level API, start with the xpc man page; this is the original source for the XPC C API documentation and still contains titbits that you can’t find elsewhere. Also read the xpcservice.plist man page, which documents the property list format used by XPC services. Daemons and Services Programming Guide archived documentation WWDC 2012 Session 241 Cocoa Interprocess Communication with XPC — This is no longer available from the Apple Developer website )-: Technote 2083 Daemons and Agents — It hasn’t been updated in… well… decades, but it’s still remarkably relevant. TN3113 Testing and Debugging XPC Code With an Anonymous Listener XPC and App-to-App Communication DevForums post Validating Signature Of XPC Process DevForums post Related tags include: Inter-process communication, for other IPC mechanisms Service Management, for installing and uninstalling Service Management login items, launchd agents, and launchd daemons Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
2.0k
Jun ’22
Swift concurrency and NSData - all threads stuck in mach_msg2_trap
I run the following code in an actor: func aaa() async throws -> Data { async let result = Task( operation: { ... decompressing data through try (data as NSData).decompressed(using: .lzfse) as Data } ).result switch await result { case .success(let value): return value case .failure(let error): throw error } I do it this way because I do not want to block the actor by decompression, and there is no state change in the actor afterwards. I would say that the actor plays no significant role here. Important is that many (14) concurrent tasks run in parallel, however NOT on the same data. It runs fine for a while (dozens/hundreds of data decompressed), and then the following happens: Activity Monitor (macOS GUI tool) shows almost none User CPU time, and approx. 75% System CPU time. The rest is idle. (When it runs fine, User CPU time is 95+%) When I pause the run in Xcode (in release config it behaves the same), all threads are in mach_msg2_trap #0 0x0000000180ac21f4 in mach_msg2_trap () #1 0x0000000180ad4b24 in mach_msg2_internal () #2 0x0000000180ac52fc in vm_copy () #3 0x0000000180916b78 in szone_realloc () #4 0x000000018093cfb0 in _malloc_zone_realloc () #5 0x000000018093d7e8 in _realloc () #6 0x0000000180bb8a10 in __CFSafelyReallocate () #7 0x0000000181d00e30 in _NSMutableDataGrowBytes () #8 0x0000000181ce2630 in -[NSConcreteMutableData appendBytes:length:] () #9 0x00000001823c30d8 in -[_NSDataCompressor processBytes:size:flags:] () #10 0x00000001823c32c4 in -[NSData(NSDataCompression) _produceDataWithCompressionOperation:algorithm:handler:] () #11 0x00000001823c3598 in -[NSData(NSDataCompression) _decompressedDataUsingCompressionAlgorithm:error:] () It looks like something is wrong with safe reallocation, however if this have been a bug, then all macOS is stuck. Any idea, please?
2
0
1k
Mar ’24
Audio Server Plugin entitlements and communication
I am currently working on planning a multi-component software system that consists of an Audio Server Plugin and an application for user interaction. I have very little experience with IPC/XPC and its performance implications, so I hope I can find a little guidance here. The Audio Server plugin publishes a number of multi-channel output devices on which it should perform computations and pass the result on to a different Core Audio device. My concerns here are: Can the plugin directly access other CoreAudio devices for audio output or is this prohibited by the sandboxing? If it cannot, would relaying the audio data via XPC be a good idea in terms of low latency stability? Can I use metal compute from within the Audio Server plugin? I have not found any information about metal related sandboxing entitlements. I am also concerned about performance implications as above. Regarding the user interface application, I would like to know: If a process that has not been started by launchd can communicate with the Audio Server plugin using XPC. If not, would a user agent instead of an app be a better choice? Or are there other communication channels that would work with sandboxing? Thank you very much! Andreas
0
0
780
Feb ’24
Looking for tutorial on how to use SwiftData correctly in background threads
Hello community, I am in search of a tutorial that comprehensively explains the proper utilization of SwiftData for updating model data in a background thread. From my understanding, there is extensive coverage on creating a model and loading model data into a view, likely due to Apple's detailed presentation on this aspect of SwiftData during WWDC23. Nevertheless, I am encountering difficulties in finding a complete tutorial that addresses the correct usage of SwiftData for model updates in a background thread. While searching the web, I came across a few discussions on Stack Overflow and this forum that potentially provide an approach. However, they were either incomplete or proved ineffective in practical application. I would greatly appreciate any links to tutorials that thoroughly cover this topic.
1
0
2k
Feb ’24
Tasks shown "alive" in Instruments display even after they should have finished.
In my TestApp I run the following code, to calculate every pixel of a bitmap concurrently: private func generate() async {     for x in 0 ..< bitmap.width{         for y in 0 ..< bitmap.height{             let result = await Task.detached(priority:.userInitiated){                return iterate(x,y)             }.value             displayResult(result)         }     } } This works and does not give any warnings or runtime issues. After watching the WWDC talk "Visualize and optimize Swift concurrency" I used instruments to visualize the Tasks: The number of active tasks continuously raises until 2740 and stays constant at this value even after all 64000 pixels have been calculated and displayed. What am I doing wrong?
2
0
1.5k
Jun ’22