Skip to content

Commit

Permalink
refactor: add lock for RETimer
Browse files Browse the repository at this point in the history
  • Loading branch information
Asura19 committed Jan 16, 2025
1 parent fe31755 commit 7263b57
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 10 deletions.
16 changes: 9 additions & 7 deletions Example/iOS_Example/iOS_Example/RETimerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,15 @@ class RETimerViewController: UIViewController {

func startTimer3() {
timeLabel3.textColor = .blue
reTimer3 = RETimer.scheduledTimer(timeInterval: 0.001) { [weak self] timer in
let minutes = Int(timer.totalElapsedTime / 60.0)
let seconds = Int(timer.totalElapsedTime - minutes.re.double * 60.0)
let minutesInMilliseconds = minutes.re.double * 60 * 1000
let secondsInMilliseconds = seconds.re.double * 1000
let milliseconds = Int(timer.totalElapsedTime * 1000 - minutesInMilliseconds - secondsInMilliseconds)
self?.timeLabel3.text = String(format: "%02d:%02d.%03d", minutes, seconds, milliseconds)
asyncOnGlobalQueue {
self.reTimer3 = RETimer.scheduledTimer(timeInterval: 0.001) { [weak self] timer in
let minutes = Int(timer.totalElapsedTime / 60.0)
let seconds = Int(timer.totalElapsedTime - minutes.re.double * 60.0)
let minutesInMilliseconds = minutes.re.double * 60 * 1000
let secondsInMilliseconds = seconds.re.double * 1000
let milliseconds = Int(timer.totalElapsedTime * 1000 - minutesInMilliseconds - secondsInMilliseconds)
self?.timeLabel3.text = String(format: "%02d:%02d.%03d", minutes, seconds, milliseconds)
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/ReerKit/Utility/PropertyWrapper/Locked.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ public final class Locked<T> {

public func read<U>(_ execute: (T) throws -> U) rethrows -> U {
os_unfair_lock_lock(lock)
defer { os_unfair_lock_unlock(lock)}
defer { os_unfair_lock_unlock(lock) }
return try execute(value)
}

@discardableResult
public func write<U>(_ execute: (inout T) throws -> U) rethrows -> U {
os_unfair_lock_lock(lock)
defer { os_unfair_lock_unlock(lock)}
defer { os_unfair_lock_unlock(lock) }
return try execute(&value)
}
}
Expand Down
21 changes: 20 additions & 1 deletion Sources/ReerKit/Utility/RETimer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#if canImport(Dispatch)

#if canImport(Dispatch) && canImport(os) && !os(Linux)
import Dispatch
import os.lock

#if canImport(Foundation)
import Foundation
Expand Down Expand Up @@ -53,6 +55,7 @@ public final class RETimer {
private var action: RETimerAction
private var callbackImmediatelyWhenFired: Bool = false
private let delay: TimeInterval
private let unfairLock: os_unfair_lock_t

/// A record for timer to count seconds when callback occurs every second.
private var secondsCount = 0
Expand Down Expand Up @@ -99,6 +102,9 @@ public final class RETimer {
self.timeInterval = max(0.0001, timeInterval)
self.callbackImmediatelyWhenFired = callbackImmediatelyWhenFired
self.delay = delay

unfairLock = .allocate(capacity: 1)
unfairLock.initialize(to: os_unfair_lock())

self.timer = DispatchSource.makeTimerSource(queue: queue)
timer.setEventHandler { [weak self] in
Expand Down Expand Up @@ -174,6 +180,8 @@ public final class RETimer {
/// ReerKit: Schedules a timer.
@discardableResult
public func schedule() -> Bool {
os_unfair_lock_lock(unfairLock)
defer { os_unfair_lock_unlock(unfairLock) }
guard state == .initial || state == .suspended else { return false }
_ = scheduleTimerOnce
timer.resume()
Expand Down Expand Up @@ -202,6 +210,8 @@ public final class RETimer {
///
/// - Important: Do NOT use `resume` to start the timer, it will not work.
public func resume() {
os_unfair_lock_lock(unfairLock)
defer { os_unfair_lock_unlock(unfairLock) }
guard state == .suspended else { return }
timer.resume()
state = .running
Expand All @@ -210,6 +220,8 @@ public final class RETimer {

/// ReerKit: Suspends the timer.
public func suspend() {
os_unfair_lock_lock(unfairLock)
defer { os_unfair_lock_unlock(unfairLock) }
guard state == .running else { return }
timer.suspend()
state = .suspended
Expand All @@ -221,6 +233,8 @@ public final class RETimer {

/// ReerKit: Stops the timer from ever firing again.
public func invalidate() {
os_unfair_lock_lock(unfairLock)
defer { os_unfair_lock_unlock(unfairLock) }
guard state != .invalidated else { return }
if state == .suspended {
timer.resume()
Expand All @@ -234,11 +248,16 @@ public final class RETimer {
}

deinit {
os_unfair_lock_lock(unfairLock)
timer.setEventHandler(handler: nil)
if state == .suspended {
timer.resume()
}
timer.cancel()
os_unfair_lock_unlock(unfairLock)

unfairLock.deinitialize(count: 1)
unfairLock.deallocate()
}
}

Expand Down

0 comments on commit 7263b57

Please sign in to comment.