Skip to content

Commit 89840c7

Browse files
authored
[dispatch] Fix + and - operations on DispatchTime and DispatchWallTime (#6961)
... for the cases where `seconds` parameter is NaN or infinite. Fixes <rdar://problem/29764171>
1 parent 0d9ff64 commit 89840c7

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

stdlib/public/SDK/Dispatch/Time.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,16 @@ public func -(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTim
111111
}
112112

113113
public func +(time: DispatchTime, seconds: Double) -> DispatchTime {
114-
let t = __dispatch_time(time.rawValue, Int64(seconds * Double(NSEC_PER_SEC)))
114+
let interval = seconds * Double(NSEC_PER_SEC)
115+
let t = __dispatch_time(time.rawValue,
116+
interval.isInfinite || interval.isNaN ? Int64.max : Int64(interval))
115117
return DispatchTime(rawValue: t)
116118
}
117119

118120
public func -(time: DispatchTime, seconds: Double) -> DispatchTime {
119-
let t = __dispatch_time(time.rawValue, Int64(-seconds * Double(NSEC_PER_SEC)))
121+
let interval = -seconds * Double(NSEC_PER_SEC)
122+
let t = __dispatch_time(time.rawValue,
123+
interval.isInfinite || interval.isNaN ? Int64.min : Int64(interval))
120124
return DispatchTime(rawValue: t)
121125
}
122126

@@ -131,11 +135,15 @@ public func -(time: DispatchWallTime, interval: DispatchTimeInterval) -> Dispatc
131135
}
132136

133137
public func +(time: DispatchWallTime, seconds: Double) -> DispatchWallTime {
134-
let t = __dispatch_time(time.rawValue, Int64(seconds * Double(NSEC_PER_SEC)))
138+
let interval = seconds * Double(NSEC_PER_SEC)
139+
let t = __dispatch_time(time.rawValue,
140+
interval.isInfinite || interval.isNaN ? Int64.max : Int64(interval))
135141
return DispatchWallTime(rawValue: t)
136142
}
137143

138144
public func -(time: DispatchWallTime, seconds: Double) -> DispatchWallTime {
139-
let t = __dispatch_time(time.rawValue, Int64(-seconds * Double(NSEC_PER_SEC)))
145+
let interval = -seconds * Double(NSEC_PER_SEC)
146+
let t = __dispatch_time(time.rawValue,
147+
interval.isInfinite || interval.isNaN ? Int64.min : Int64(interval))
140148
return DispatchWallTime(rawValue: t)
141149
}

test/stdlib/Dispatch.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,31 @@ DispatchAPI.test("DispatchTime comparisons") {
101101
})
102102
}
103103
}
104+
105+
DispatchAPI.test("DispatchTime.addSubtract") {
106+
var then = DispatchTime.now() + Double.infinity
107+
expectEqual(DispatchTime.distantFuture, then)
108+
109+
then = DispatchTime.now() + Double.nan
110+
expectEqual(DispatchTime.distantFuture, then)
111+
112+
then = DispatchTime.now() - Double.infinity
113+
expectEqual(DispatchTime(uptimeNanoseconds: 1), then)
114+
115+
then = DispatchTime.now() - Double.nan
116+
expectEqual(DispatchTime(uptimeNanoseconds: 1), then)
117+
}
118+
119+
DispatchAPI.test("DispatchWallTime.addSubtract") {
120+
var then = DispatchWallTime.now() + Double.infinity
121+
expectEqual(DispatchWallTime.distantFuture, then)
122+
123+
then = DispatchWallTime.now() + Double.nan
124+
expectEqual(DispatchWallTime.distantFuture, then)
125+
126+
then = DispatchWallTime.now() - Double.infinity
127+
expectEqual(DispatchWallTime.distantFuture.rawValue - UInt64(1), then.rawValue)
128+
129+
then = DispatchWallTime.now() - Double.nan
130+
expectEqual(DispatchWallTime.distantFuture.rawValue - UInt64(1), then.rawValue)
131+
}

0 commit comments

Comments
 (0)