From 4bdba507fd30176c57d965faa72090c2a713ce59 Mon Sep 17 00:00:00 2001 From: "Daniela P. Riesgo" Date: Tue, 12 May 2020 14:03:43 -0300 Subject: [PATCH 1/3] Correctly use pointer --- Sources/KqueueSelector.swift | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/Sources/KqueueSelector.swift b/Sources/KqueueSelector.swift index e8d2817..17e0483 100644 --- a/Sources/KqueueSelector.swift +++ b/Sources/KqueueSelector.swift @@ -66,13 +66,8 @@ public final class KqueueSelector: Selector { } // register events to kqueue - - // Notice: we need to get the event count before we go into - // `withUnsafeMutableBufferPointer`, as we cannot rely on it inside the closure - // (you can read the offical document) - let keventCount = kevents.count guard kevents.withUnsafeMutableBufferPointer({ pointer in - kevent(kqueue, pointer.baseAddress, Int32(keventCount), nil, Int32(0), nil) >= 0 + kevent(kqueue, pointer.baseAddress, Int32(pointer.count), nil, Int32(0), nil) >= 0 }) else { throw OSError.lastIOError() } @@ -107,13 +102,8 @@ public final class KqueueSelector: Selector { } // unregister events from kqueue - - // Notice: we need to get the event count before we go into - // `withUnsafeMutableBufferPointer`, as we cannot rely on it inside the closure - // (you can read the offical document) - let keventCount = kevents.count guard kevents.withUnsafeMutableBufferPointer({ pointer in - kevent(kqueue, pointer.baseAddress, Int32(keventCount), nil, Int32(0), nil) >= 0 + kevent(kqueue, pointer.baseAddress, Int32(pointer.count), nil, Int32(0), nil) >= 0 }) else { throw OSError.lastIOError() } From 79ca98b03e0e50b96a93bacd77c8b030dd77d245 Mon Sep 17 00:00:00 2001 From: "Daniela P. Riesgo" Date: Tue, 12 May 2020 14:19:14 -0300 Subject: [PATCH 2/3] Copy fix #83 --- Sources/KqueueSelector.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/KqueueSelector.swift b/Sources/KqueueSelector.swift index 17e0483..dc5222b 100644 --- a/Sources/KqueueSelector.swift +++ b/Sources/KqueueSelector.swift @@ -157,7 +157,9 @@ public final class KqueueSelector: Selector { } fileDescriptorIOEvents[fileDescriptor] = ioEvents } - return Array(fileDescriptorIOEvents.map { (fileDescriptorMap[$0.0]!, $0.1) }) + return Array(fileDescriptorIOEvents.compactMap { event in + fileDescriptorMap[event.0].map { ($0, event.1) } ?? nil + }) } public subscript(fileDescriptor: Int32) -> SelectorKey? { From 6f24fa60a30d52e08d1e326809f96519e616b879 Mon Sep 17 00:00:00 2001 From: Juan Barreneche Date: Wed, 13 May 2020 12:32:25 -0300 Subject: [PATCH 3/3] Fix incorrect use of unsafepointer --- Sources/KqueueSelector.swift | 40 +++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Sources/KqueueSelector.swift b/Sources/KqueueSelector.swift index dc5222b..6c27a89 100644 --- a/Sources/KqueueSelector.swift +++ b/Sources/KqueueSelector.swift @@ -116,7 +116,6 @@ public final class KqueueSelector: Selector { public func select(timeout: TimeInterval?) throws -> [(SelectorKey, Set)] { var timeSpec: timespec? - let timeSpecPointer: UnsafePointer? if let timeout = timeout { if timeout > 0 { var integer = 0.0 @@ -125,21 +124,20 @@ public final class KqueueSelector: Selector { } else { timeSpec = timespec() } - timeSpecPointer = withUnsafePointer(to: &timeSpec!) { $0 } - } else { - timeSpecPointer = nil } var kevents = Array(repeating: Darwin.kevent(), count: selectMaximumEvent) - let eventCount = kevents.withUnsafeMutableBufferPointer { pointer in - return kevent( - kqueue, - nil, - 0, - pointer.baseAddress, - Int32(selectMaximumEvent), - timeSpecPointer - ) + let eventCount:Int32 = kevents.withUnsafeMutableBufferPointer { pointer in + return withUnsafeOptionalPointer(to: &timeSpec) { timeSpecPointer in + return kevent( + kqueue, + nil, + 0, + pointer.baseAddress, + Int32(selectMaximumEvent), + timeSpecPointer + ) + } } guard eventCount >= 0 else { throw OSError.lastIOError() @@ -157,9 +155,10 @@ public final class KqueueSelector: Selector { } fileDescriptorIOEvents[fileDescriptor] = ioEvents } - return Array(fileDescriptorIOEvents.compactMap { event in - fileDescriptorMap[event.0].map { ($0, event.1) } ?? nil - }) + let fdMap = fileDescriptorMap + return fileDescriptorIOEvents.compactMap { [weak self] event in + fdMap[event.0].map { ($0, event.1) } ?? nil + } } public subscript(fileDescriptor: Int32) -> SelectorKey? { @@ -167,6 +166,15 @@ public final class KqueueSelector: Selector { return fileDescriptorMap[fileDescriptor] } } + + private func withUnsafeOptionalPointer(to: inout T?, body: (UnsafePointer?) throws -> Result) rethrows -> Result { + if to != nil { + return try withUnsafePointer(to: &to!) { try body($0) } + } else { + return try body(nil) + } + } + } #endif