From 610463dc985e1d01672b18676d2699b2a8404b7f Mon Sep 17 00:00:00 2001 From: Victor Herrero Date: Fri, 22 Mar 2024 18:46:35 +0100 Subject: [PATCH 1/8] Make DNSSD queries cancellable Resolves https://github.com/apple/swift-async-dns-resolver/issues/32 --- .../dnssd/DNSResolver_dnssd.swift | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift index 29c306e..0c52c58 100644 --- a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift +++ b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift @@ -141,6 +141,10 @@ struct DNSSD { let serviceRefPtr = UnsafeMutablePointer.allocate(capacity: 1) defer { serviceRefPtr.deallocate() } + continuation.onTermination = { _ in + DNSServiceRefDeallocate(serviceRefPtr.pointee) + } + // Run the query let _code = DNSServiceQueryRecord( serviceRefPtr, @@ -158,9 +162,32 @@ struct DNSSD { return continuation.finish(throwing: AsyncDNSResolver.Error(dnssdCode: _code)) } + let serviceSockFD = DNSServiceRefSockFD(serviceRefPtr.pointee) + guard serviceSockFD != -1 else { + return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError)) + } + + var pollFDs = [pollfd(fd: serviceSockFD, events: Int16(POLLIN), revents: 0)] + while true { + guard !Task.isCancelled else { + return continuation.finish(throwing: CancellationError()) + } + + let result = poll(&pollFDs, 1, 0) + guard result != -1 else { + return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError)) + } + + if result == 0 { + continue + } + if result == 1 { + break + } + } + // Read reply from the socket (blocking) then call reply handler DNSServiceProcessResult(serviceRefPtr.pointee) - DNSServiceRefDeallocate(serviceRefPtr.pointee) // Streaming done continuation.finish() From a6299e5b79ed6564aeb8870cb0b2f95e7dcc2ee3 Mon Sep 17 00:00:00 2001 From: Victor Herrero Date: Fri, 22 Mar 2024 20:39:40 +0100 Subject: [PATCH 2/8] Improve error handling and remove DNSServiceRef Sendable warning Add AsyncDNSResolver.Error.cancelled and error messages when polling the DNSSD service socket --- Sources/AsyncDNSResolver/Errors.swift | 6 ++++++ Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift | 9 ++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Sources/AsyncDNSResolver/Errors.swift b/Sources/AsyncDNSResolver/Errors.swift index 21ada88..2ff8383 100644 --- a/Sources/AsyncDNSResolver/Errors.swift +++ b/Sources/AsyncDNSResolver/Errors.swift @@ -23,6 +23,7 @@ extension AsyncDNSResolver { case connectionRefused case timeout case internalError + case cancelled } fileprivate var value: Value @@ -44,6 +45,9 @@ extension AsyncDNSResolver { /// An internal error. public static var internalError: Self { Self(.internalError) } + + /// The query was cancelled. + public static var cancelled: Self { Self(.cancelled) } } public var code: Code @@ -69,6 +73,8 @@ extension AsyncDNSResolver { name = "timeout" case .internalError: name = "internal" + case .cancelled: + name = "cancelled" } let suffix = self.source.map { " (\($0))" } ?? "" diff --git a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift index 0c52c58..1d33175 100644 --- a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift +++ b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift @@ -164,18 +164,18 @@ struct DNSSD { let serviceSockFD = DNSServiceRefSockFD(serviceRefPtr.pointee) guard serviceSockFD != -1 else { - return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError)) + return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError, message: "Failed to access the DNSSD service socket")) } var pollFDs = [pollfd(fd: serviceSockFD, events: Int16(POLLIN), revents: 0)] while true { guard !Task.isCancelled else { - return continuation.finish(throwing: CancellationError()) + return continuation.finish(throwing: AsyncDNSResolver.Error(code: .cancelled)) } let result = poll(&pollFDs, 1, 0) guard result != -1 else { - return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError)) + return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError, message: "Failed to poll the DNSSD service socket")) } if result == 0 { @@ -202,6 +202,9 @@ struct DNSSD { } } +// Needed to remove the Sendable warning when deallocating DNSServiceRef in onTermination callback +extension UnsafeMutablePointer: @unchecked Sendable where Pointee == DNSServiceRef? {} + // MARK: - dnssd query reply handler @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) From de2fd16e871eeaf79fa3bb8741e9f3a346ba394f Mon Sep 17 00:00:00 2001 From: Victor Herrero Date: Tue, 9 Apr 2024 10:24:46 +0200 Subject: [PATCH 3/8] Use DispatchReadSource to process DNSSD results Convert DNSSD to class to use deinit on the pointers we initialized for dns-sd C functions The Dispatch Source event handler is called when data can be read from the DNSSD service socket Remove the unchecked Sendable subtyping for the DNSServiceRef pointer as it's no longer needed Remove the cancelled case from the error code enum as it's no longer needed --- Sources/AsyncDNSResolver/Errors.swift | 6 -- .../dnssd/DNSResolver_dnssd.swift | 75 +++++++------------ 2 files changed, 28 insertions(+), 53 deletions(-) diff --git a/Sources/AsyncDNSResolver/Errors.swift b/Sources/AsyncDNSResolver/Errors.swift index 2ff8383..21ada88 100644 --- a/Sources/AsyncDNSResolver/Errors.swift +++ b/Sources/AsyncDNSResolver/Errors.swift @@ -23,7 +23,6 @@ extension AsyncDNSResolver { case connectionRefused case timeout case internalError - case cancelled } fileprivate var value: Value @@ -45,9 +44,6 @@ extension AsyncDNSResolver { /// An internal error. public static var internalError: Self { Self(.internalError) } - - /// The query was cancelled. - public static var cancelled: Self { Self(.cancelled) } } public var code: Code @@ -73,8 +69,6 @@ extension AsyncDNSResolver { name = "timeout" case .internalError: name = "internal" - case .cancelled: - name = "cancelled" } let suffix = self.source.map { " (\($0))" } ?? "" diff --git a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift index 1d33175..2ae07b7 100644 --- a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift +++ b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift @@ -100,7 +100,21 @@ extension QueryType { // MARK: - dnssd query wrapper @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -struct DNSSD { +class DNSSD { + private let serviceRefPtr = UnsafeMutablePointer.allocate(capacity: 1) + + // Wrap `handler` into a pointer so we can pass it to DNSServiceQueryRecord + private let replyHandlerPointer = UnsafeMutableRawPointer.allocate( + byteCount: MemoryLayout.stride, + alignment: MemoryLayout.alignment + ) + deinit { + serviceRefPtr.deallocate() + let pointer = replyHandlerPointer.assumingMemoryBound(to: QueryReplyHandler.self) + pointer.deinitialize(count: 1) + pointer.deallocate() + } + // Reference: https://gist.github.com/fikeminkel/a9c4bc4d0348527e8df3690e242038d3 func query( type: QueryType, @@ -110,20 +124,7 @@ struct DNSSD { let recordStream = AsyncThrowingStream { continuation in let handler = QueryReplyHandler(handler: replyHandler, continuation) - // Wrap `handler` into a pointer so we can pass it to DNSServiceQueryRecord - let handlerPointer = UnsafeMutableRawPointer.allocate( - byteCount: MemoryLayout.stride, - alignment: MemoryLayout.alignment - ) - - handlerPointer.initializeMemory(as: QueryReplyHandler.self, repeating: handler, count: 1) - - // The handler might be called multiple times so don't deallocate inside `callback` - defer { - let pointer = handlerPointer.assumingMemoryBound(to: QueryReplyHandler.self) - pointer.deinitialize(count: 1) - pointer.deallocate() - } + self.replyHandlerPointer.initializeMemory(as: QueryReplyHandler.self, repeating: handler, count: 1) // This is called once per record received let callback: DNSServiceQueryRecordReply = { _, _, _, errorCode, _, _, _, rdlen, rdata, _, context in @@ -138,13 +139,6 @@ struct DNSSD { handler.handleRecord(errorCode: errorCode, data: rdata, length: rdlen) } - let serviceRefPtr = UnsafeMutablePointer.allocate(capacity: 1) - defer { serviceRefPtr.deallocate() } - - continuation.onTermination = { _ in - DNSServiceRefDeallocate(serviceRefPtr.pointee) - } - // Run the query let _code = DNSServiceQueryRecord( serviceRefPtr, @@ -154,7 +148,7 @@ struct DNSSD { UInt16(type.kDNSServiceType), UInt16(kDNSServiceClass_IN), callback, - handlerPointer + self.replyHandlerPointer ) // Check if query completed successfully @@ -167,30 +161,20 @@ struct DNSSD { return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError, message: "Failed to access the DNSSD service socket")) } - var pollFDs = [pollfd(fd: serviceSockFD, events: Int16(POLLIN), revents: 0)] - while true { - guard !Task.isCancelled else { - return continuation.finish(throwing: AsyncDNSResolver.Error(code: .cancelled)) - } + let readSource = DispatchSource.makeReadSource(fileDescriptor: serviceSockFD) + readSource.setEventHandler { + // Read reply from the socket (blocking) then call reply handler + DNSServiceProcessResult(self.serviceRefPtr.pointee) - let result = poll(&pollFDs, 1, 0) - guard result != -1 else { - return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError, message: "Failed to poll the DNSSD service socket")) - } - - if result == 0 { - continue - } - if result == 1 { - break - } + // Streaming done + continuation.finish() } + readSource.resume() - // Read reply from the socket (blocking) then call reply handler - DNSServiceProcessResult(serviceRefPtr.pointee) - - // Streaming done - continuation.finish() + continuation.onTermination = { _ in + readSource.cancel() + DNSServiceRefDeallocate(self.serviceRefPtr.pointee) + } } // Build reply using records received @@ -202,9 +186,6 @@ struct DNSSD { } } -// Needed to remove the Sendable warning when deallocating DNSServiceRef in onTermination callback -extension UnsafeMutablePointer: @unchecked Sendable where Pointee == DNSServiceRef? {} - // MARK: - dnssd query reply handler @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) From 8be4b7ddf39b055c07c61b1c1007bbeab592c3e5 Mon Sep 17 00:00:00 2001 From: Victor Herrero Date: Tue, 9 Apr 2024 18:46:19 +0200 Subject: [PATCH 4/8] Add Query class to handle queries' pointers Convert DNSSD back to struct A different Query class is created for every query, so concurrent queries no longer cause an issue --- .../dnssd/DNSResolver_dnssd.swift | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift index 2ae07b7..79b3076 100644 --- a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift +++ b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift @@ -100,20 +100,7 @@ extension QueryType { // MARK: - dnssd query wrapper @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -class DNSSD { - private let serviceRefPtr = UnsafeMutablePointer.allocate(capacity: 1) - - // Wrap `handler` into a pointer so we can pass it to DNSServiceQueryRecord - private let replyHandlerPointer = UnsafeMutableRawPointer.allocate( - byteCount: MemoryLayout.stride, - alignment: MemoryLayout.alignment - ) - deinit { - serviceRefPtr.deallocate() - let pointer = replyHandlerPointer.assumingMemoryBound(to: QueryReplyHandler.self) - pointer.deinitialize(count: 1) - pointer.deallocate() - } +struct DNSSD { // Reference: https://gist.github.com/fikeminkel/a9c4bc4d0348527e8df3690e242038d3 func query( @@ -124,7 +111,7 @@ class DNSSD { let recordStream = AsyncThrowingStream { continuation in let handler = QueryReplyHandler(handler: replyHandler, continuation) - self.replyHandlerPointer.initializeMemory(as: QueryReplyHandler.self, repeating: handler, count: 1) + let query = Query(handler: handler) // This is called once per record received let callback: DNSServiceQueryRecordReply = { _, _, _, errorCode, _, _, _, rdlen, rdata, _, context in @@ -141,14 +128,14 @@ class DNSSD { // Run the query let _code = DNSServiceQueryRecord( - serviceRefPtr, + query.serviceRefPtr, kDNSServiceFlagsTimeout, 0, name, UInt16(type.kDNSServiceType), UInt16(kDNSServiceClass_IN), callback, - self.replyHandlerPointer + query.replyHandlerPointer ) // Check if query completed successfully @@ -156,7 +143,7 @@ class DNSSD { return continuation.finish(throwing: AsyncDNSResolver.Error(dnssdCode: _code)) } - let serviceSockFD = DNSServiceRefSockFD(serviceRefPtr.pointee) + let serviceSockFD = DNSServiceRefSockFD(query.serviceRefPtr.pointee) guard serviceSockFD != -1 else { return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError, message: "Failed to access the DNSSD service socket")) } @@ -164,7 +151,7 @@ class DNSSD { let readSource = DispatchSource.makeReadSource(fileDescriptor: serviceSockFD) readSource.setEventHandler { // Read reply from the socket (blocking) then call reply handler - DNSServiceProcessResult(self.serviceRefPtr.pointee) + DNSServiceProcessResult(query.serviceRefPtr.pointee) // Streaming done continuation.finish() @@ -173,7 +160,7 @@ class DNSSD { continuation.onTermination = { _ in readSource.cancel() - DNSServiceRefDeallocate(self.serviceRefPtr.pointee) + DNSServiceRefDeallocate(query.serviceRefPtr.pointee) } } @@ -190,6 +177,27 @@ class DNSSD { @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) extension DNSSD { + // Class used to manage both the handler and the serviceRef pointers, so that they are deallocated when we are done using them + class Query { + let serviceRefPtr = UnsafeMutablePointer.allocate(capacity: 1) + + let replyHandlerPointer = UnsafeMutableRawPointer.allocate( + byteCount: MemoryLayout.stride, + alignment: MemoryLayout.alignment + ) + init(handler: QueryReplyHandler) { + // Wrap 'handler' into a pointer so we can pass it to DNSServiceQueryRecord + self.replyHandlerPointer.initializeMemory(as: QueryReplyHandler.self, repeating: handler, count: 1) + } + + deinit { + serviceRefPtr.deallocate() + let pointer = replyHandlerPointer.assumingMemoryBound(to: QueryReplyHandler.self) + pointer.deinitialize(count: 1) + pointer.deallocate() + } + } + class QueryReplyHandler { private let _handleRecord: (DNSServiceErrorType, UnsafeRawPointer?, UInt16) -> Void From 472d5c0f29a2deff12c8a7c3667f187b6e08f170 Mon Sep 17 00:00:00 2001 From: Victor Herrero Date: Tue, 9 Apr 2024 18:48:27 +0200 Subject: [PATCH 5/8] Fix formatting --- Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift index 79b3076..a9eb63d 100644 --- a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift +++ b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift @@ -101,7 +101,6 @@ extension QueryType { @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) struct DNSSD { - // Reference: https://gist.github.com/fikeminkel/a9c4bc4d0348527e8df3690e242038d3 func query( type: QueryType, From 6ad9bd9ce6eb03ee3f688c1f9ea84f7a092d754c Mon Sep 17 00:00:00 2001 From: Victor Herrero Date: Thu, 11 Apr 2024 18:28:08 +0200 Subject: [PATCH 6/8] Add cancel handler to manage resources instead of Query class DNSServiceRefDeallocate is called in the DispatchSource cancellation handler to be sure it's not used in the event handler after being freed Remove Query class as it is not needed for pointer management Close DNSServiceRefSockFD in DispatchSource cancellation handler to avoid any FD leak --- .../dnssd/DNSResolver_dnssd.swift | 47 +++++++------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift index a9eb63d..083e30e 100644 --- a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift +++ b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift @@ -110,8 +110,6 @@ struct DNSSD { let recordStream = AsyncThrowingStream { continuation in let handler = QueryReplyHandler(handler: replyHandler, continuation) - let query = Query(handler: handler) - // This is called once per record received let callback: DNSServiceQueryRecordReply = { _, _, _, errorCode, _, _, _, rdlen, rdata, _, context in guard let handlerPointer = context else { @@ -125,16 +123,22 @@ struct DNSSD { handler.handleRecord(errorCode: errorCode, data: rdata, length: rdlen) } + let serviceRefPointer = UnsafeMutablePointer.allocate(capacity: 1) + + // Wrap 'handler' into a pointer so we can pass it to DNSServiceQueryRecord + let replyHandlerPointer = UnsafeMutablePointer.allocate(capacity: 1) + replyHandlerPointer.initialize(repeating: handler, count: 1) + // Run the query let _code = DNSServiceQueryRecord( - query.serviceRefPtr, + serviceRefPointer, kDNSServiceFlagsTimeout, 0, name, UInt16(type.kDNSServiceType), UInt16(kDNSServiceClass_IN), callback, - query.replyHandlerPointer + replyHandlerPointer ) // Check if query completed successfully @@ -142,7 +146,7 @@ struct DNSSD { return continuation.finish(throwing: AsyncDNSResolver.Error(dnssdCode: _code)) } - let serviceSockFD = DNSServiceRefSockFD(query.serviceRefPtr.pointee) + let serviceSockFD = DNSServiceRefSockFD(serviceRefPointer.pointee) guard serviceSockFD != -1 else { return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError, message: "Failed to access the DNSSD service socket")) } @@ -150,16 +154,22 @@ struct DNSSD { let readSource = DispatchSource.makeReadSource(fileDescriptor: serviceSockFD) readSource.setEventHandler { // Read reply from the socket (blocking) then call reply handler - DNSServiceProcessResult(query.serviceRefPtr.pointee) + DNSServiceProcessResult(serviceRefPointer.pointee) - // Streaming done + readSource.cancel() continuation.finish() } + + readSource.setCancelHandler { + DNSServiceRefDeallocate(serviceRefPointer.pointee) + close(serviceSockFD) + serviceRefPointer.deallocate() + replyHandlerPointer.deallocate() + } readSource.resume() continuation.onTermination = { _ in readSource.cancel() - DNSServiceRefDeallocate(query.serviceRefPtr.pointee) } } @@ -176,27 +186,6 @@ struct DNSSD { @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) extension DNSSD { - // Class used to manage both the handler and the serviceRef pointers, so that they are deallocated when we are done using them - class Query { - let serviceRefPtr = UnsafeMutablePointer.allocate(capacity: 1) - - let replyHandlerPointer = UnsafeMutableRawPointer.allocate( - byteCount: MemoryLayout.stride, - alignment: MemoryLayout.alignment - ) - init(handler: QueryReplyHandler) { - // Wrap 'handler' into a pointer so we can pass it to DNSServiceQueryRecord - self.replyHandlerPointer.initializeMemory(as: QueryReplyHandler.self, repeating: handler, count: 1) - } - - deinit { - serviceRefPtr.deallocate() - let pointer = replyHandlerPointer.assumingMemoryBound(to: QueryReplyHandler.self) - pointer.deinitialize(count: 1) - pointer.deallocate() - } - } - class QueryReplyHandler { private let _handleRecord: (DNSServiceErrorType, UnsafeRawPointer?, UInt16) -> Void From 8102fb42e22b3803f6e2e9cda58862384f8f43fa Mon Sep 17 00:00:00 2001 From: Victor Herrero Date: Tue, 30 Apr 2024 17:35:17 +0200 Subject: [PATCH 7/8] Deallocate pointers in error branches too --- .../AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift index 083e30e..6f96eb6 100644 --- a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift +++ b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift @@ -143,11 +143,13 @@ struct DNSSD { // Check if query completed successfully guard _code == kDNSServiceErr_NoError else { + self.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) return continuation.finish(throwing: AsyncDNSResolver.Error(dnssdCode: _code)) } let serviceSockFD = DNSServiceRefSockFD(serviceRefPointer.pointee) guard serviceSockFD != -1 else { + self.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError, message: "Failed to access the DNSSD service socket")) } @@ -161,10 +163,8 @@ struct DNSSD { } readSource.setCancelHandler { - DNSServiceRefDeallocate(serviceRefPointer.pointee) + self.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) close(serviceSockFD) - serviceRefPointer.deallocate() - replyHandlerPointer.deallocate() } readSource.resume() @@ -180,6 +180,12 @@ struct DNSSD { return try replyHandler.generateReply(records: records) } + + private func deallocatePointers(serviceRefPointer: UnsafeMutablePointer, replyHandlerPointer: UnsafeMutablePointer) { + DNSServiceRefDeallocate(serviceRefPointer.pointee) + serviceRefPointer.deallocate() + replyHandlerPointer.deallocate() + } } // MARK: - dnssd query reply handler From 792d8e1ebd0b4652877616e75734a769a60ae841 Mon Sep 17 00:00:00 2001 From: Victor Herrero Date: Tue, 14 May 2024 10:45:13 +0200 Subject: [PATCH 8/8] Convert deallocatePointers to static and use initialize(to:) for the reply handler pointer --- Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift index 6f96eb6..bc857ad 100644 --- a/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift +++ b/Sources/AsyncDNSResolver/dnssd/DNSResolver_dnssd.swift @@ -127,7 +127,7 @@ struct DNSSD { // Wrap 'handler' into a pointer so we can pass it to DNSServiceQueryRecord let replyHandlerPointer = UnsafeMutablePointer.allocate(capacity: 1) - replyHandlerPointer.initialize(repeating: handler, count: 1) + replyHandlerPointer.initialize(to: handler) // Run the query let _code = DNSServiceQueryRecord( @@ -143,13 +143,13 @@ struct DNSSD { // Check if query completed successfully guard _code == kDNSServiceErr_NoError else { - self.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) + DNSSD.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) return continuation.finish(throwing: AsyncDNSResolver.Error(dnssdCode: _code)) } let serviceSockFD = DNSServiceRefSockFD(serviceRefPointer.pointee) guard serviceSockFD != -1 else { - self.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) + DNSSD.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) return continuation.finish(throwing: AsyncDNSResolver.Error(code: .internalError, message: "Failed to access the DNSSD service socket")) } @@ -163,7 +163,7 @@ struct DNSSD { } readSource.setCancelHandler { - self.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) + DNSSD.deallocatePointers(serviceRefPointer: serviceRefPointer, replyHandlerPointer: replyHandlerPointer) close(serviceSockFD) } readSource.resume() @@ -181,7 +181,7 @@ struct DNSSD { return try replyHandler.generateReply(records: records) } - private func deallocatePointers(serviceRefPointer: UnsafeMutablePointer, replyHandlerPointer: UnsafeMutablePointer) { + private static func deallocatePointers(serviceRefPointer: UnsafeMutablePointer, replyHandlerPointer: UnsafeMutablePointer) { DNSServiceRefDeallocate(serviceRefPointer.pointee) serviceRefPointer.deallocate() replyHandlerPointer.deallocate()