Skip to content

Commit

Permalink
Switch to CFRunLoop for multithreading
Browse files Browse the repository at this point in the history
  • Loading branch information
EricRabil committed Sep 9, 2021
1 parent 40bb96f commit 7d6fe2b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
10 changes: 8 additions & 2 deletions Sources/BarcelonaIPC/IPCReceiver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ private extension PortMessage {
}
#endif

public extension CFRunLoop {
static var main: CFRunLoop {
CFRunLoopGetMain()
}
}

public class IPCReceiver<PayloadType: RawRepresentable>: IPCWrapper<PayloadType>, PortDelegate where PayloadType.RawValue == UInt, PayloadType: Codable {
public typealias ReceiverCallback = (Payload, IPCSender<PayloadType>?, IPCReceiver) -> ()

public static func anonymousReceiver(loop: RunLoop = .main, _ responseHandler: @escaping ReceiverCallback) -> IPCReceiver {
public static func anonymousReceiver(loop: CFRunLoop = .main, _ responseHandler: @escaping ReceiverCallback) -> IPCReceiver {
IPCReceiver(port: IPCReceivePort(loop: loop), mine: true, handleResponse: responseHandler)
}

public static func serverReceiver(named name: String, loop: RunLoop = .main, _ responseHandler: @escaping ReceiverCallback) -> IPCReceiver {
public static func serverReceiver(named name: String, loop: CFRunLoop = .main, _ responseHandler: @escaping ReceiverCallback) -> IPCReceiver {
var existingPort: mach_port_t = 0

if bootstrap_check_in(bootstrap_port, name, &existingPort) == KERN_SUCCESS, existingPort != 0 {
Expand Down
15 changes: 12 additions & 3 deletions Sources/BarcelonaIPC/IPCUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,23 @@ func bootstrap_look_up2(_ bootstrap: mach_port_t, _ name: UnsafePointer<CChar>,
internal let decoder = JSONDecoder()
internal let encoder = JSONEncoder()

internal func IPCWrapPort(_ port: mach_port_t, loop: RunLoop) -> NSMachPort {
internal func IPCWrapPort(_ port: mach_port_t, loop: CFRunLoop) -> NSMachPort {
let port = NSMachPort(machPort: port)
loop.add(port, forMode: .default)
let source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, port, 0)

CFRunLoopAddSource(loop, source, .commonModes)

var observer: NSObjectProtocol?
observer = NotificationCenter.default.addObserver(forName: Port.didBecomeInvalidNotification, object: port, queue: .main) { notification in
CFRunLoopRemoveSource(loop, source, .commonModes)
NotificationCenter.default.removeObserver(observer!)
observer = nil
}

return port
}

internal func IPCReceivePort(loop: RunLoop) -> NSMachPort {
internal func IPCReceivePort(loop: CFRunLoop) -> NSMachPort {
var rcv_port: mach_port_name_t = 0

guard mach_port_allocate(mach_task_self_, MACH_PORT_RIGHT_RECEIVE, &rcv_port) == KERN_SUCCESS else {
Expand Down

0 comments on commit 7d6fe2b

Please sign in to comment.