Skip to content

Commit

Permalink
修复 Debouncer 线程安全问题
Browse files Browse the repository at this point in the history
  • Loading branch information
liujunhua committed Sep 1, 2021
1 parent 44365f5 commit 4b35a98
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 63 deletions.
10 changes: 5 additions & 5 deletions Sources/General/DownloadTask.swift
Expand Up @@ -51,7 +51,7 @@ public class DownloadTask: Task<DownloadTask> {


public internal(set) var response: HTTPURLResponse? {
get { protectedDownloadState.directValue.response }
get { protectedDownloadState.wrappedValue.response }
set { protectedDownloadState.write { $0.response = newValue } }
}

Expand Down Expand Up @@ -81,20 +81,20 @@ public class DownloadTask: Task<DownloadTask> {
var shouldValidateFile: Bool = false
}

private let protectedDownloadState: Protector<DownloadState> = Protector(DownloadState())
private let protectedDownloadState: Protected<DownloadState> = Protected(DownloadState())


private var resumeData: Data? {
get { protectedDownloadState.directValue.resumeData }
get { protectedDownloadState.wrappedValue.resumeData }
set { protectedDownloadState.write { $0.resumeData = newValue } }
}

internal var tmpFileName: String? {
protectedDownloadState.directValue.tmpFileName
protectedDownloadState.wrappedValue.tmpFileName
}

private var shouldValidateFile: Bool {
get { protectedDownloadState.directValue.shouldValidateFile }
get { protectedDownloadState.wrappedValue.shouldValidateFile }
set { protectedDownloadState.write { $0.shouldValidateFile = newValue } }
}

Expand Down
@@ -1,5 +1,5 @@
//
// Protector.swift
// Protected.swift
// Tiercel
//
// Created by Daniels on 2020/1/9.
Expand Down Expand Up @@ -62,20 +62,29 @@ final public class UnfairLock {
}
}

final public class Protector<T> {
@propertyWrapper
final public class Protected<T> {

private let lock = UnfairLock()

private var value: T

public var wrappedValue: T {
get { lock.around { value } }
set { lock.around { value = newValue } }
}

public var projectedValue: Protected<T> { self }


public init(_ value: T) {
self.value = value
}

public var directValue: T {
get { return lock.around { value } }
set { lock.around { value = newValue } }

public init(wrappedValue: T) {
value = wrappedValue
}


public func read<U>(_ closure: (T) throws -> U) rethrows -> U {
return try lock.around { try closure(self.value) }
}
Expand All @@ -93,6 +102,7 @@ final public class Debouncer {

private var queue: DispatchQueue

@Protected
private var workItems = [String: DispatchWorkItem]()

public init(queue: DispatchQueue) {
Expand Down
42 changes: 21 additions & 21 deletions Sources/General/SessionManager.swift
Expand Up @@ -45,7 +45,7 @@ public class SessionManager {
public var completionHandler: (() -> Void)?

public var configuration: SessionConfiguration {
get { protectedState.directValue.configuration }
get { protectedState.wrappedValue.configuration }
set {
operationQueue.sync {
protectedState.write {
Expand Down Expand Up @@ -98,15 +98,15 @@ public class SessionManager {
}


private let protectedState: Protector<State>
private let protectedState: Protected<State>

public var logger: Logable {
get { protectedState.directValue.logger }
get { protectedState.wrappedValue.logger }
set { protectedState.write { $0.logger = newValue } }
}

public var isControlNetworkActivityIndicator: Bool {
get { protectedState.directValue.isControlNetworkActivityIndicator }
get { protectedState.wrappedValue.isControlNetworkActivityIndicator }
set { protectedState.write { $0.isControlNetworkActivityIndicator = newValue } }
}

Expand All @@ -116,24 +116,24 @@ public class SessionManager {
}

private var session: URLSession? {
get { protectedState.directValue.session }
get { protectedState.wrappedValue.session }
set { protectedState.write { $0.session = newValue } }
}

private var shouldCreatSession: Bool {
get { protectedState.directValue.shouldCreatSession }
get { protectedState.wrappedValue.shouldCreatSession }
set { protectedState.write { $0.shouldCreatSession = newValue } }
}


private var timer: DispatchSourceTimer? {
get { protectedState.directValue.timer }
get { protectedState.wrappedValue.timer }
set { protectedState.write { $0.timer = newValue } }
}


public private(set) var status: Status {
get { protectedState.directValue.status }
get { protectedState.wrappedValue.status }
set {
protectedState.write { $0.status = newValue }
if newValue == .willSuspend || newValue == .willCancel || newValue == .willRemove {
Expand All @@ -145,22 +145,22 @@ public class SessionManager {


public private(set) var tasks: [DownloadTask] {
get { protectedState.directValue.tasks }
get { protectedState.wrappedValue.tasks }
set { protectedState.write { $0.tasks = newValue } }
}

private var runningTasks: [DownloadTask] {
get { protectedState.directValue.runningTasks }
get { protectedState.wrappedValue.runningTasks }
set { protectedState.write { $0.runningTasks = newValue } }
}

private var restartTasks: [DownloadTask] {
get { protectedState.directValue.restartTasks }
get { protectedState.wrappedValue.restartTasks }
set { protectedState.write { $0.restartTasks = newValue } }
}

public private(set) var succeededTasks: [DownloadTask] {
get { protectedState.directValue.succeededTasks }
get { protectedState.wrappedValue.succeededTasks }
set { protectedState.write { $0.succeededTasks = newValue } }
}

Expand All @@ -172,7 +172,7 @@ public class SessionManager {
}

public private(set) var speed: Int64 {
get { protectedState.directValue.speed }
get { protectedState.wrappedValue.speed }
set { protectedState.write { $0.speed = newValue } }
}

Expand All @@ -182,7 +182,7 @@ public class SessionManager {


public private(set) var timeRemaining: Int64 {
get { protectedState.directValue.timeRemaining }
get { protectedState.wrappedValue.timeRemaining }
set { protectedState.write { $0.timeRemaining = newValue } }
}

Expand All @@ -191,27 +191,27 @@ public class SessionManager {
}

private var progressExecuter: Executer<SessionManager>? {
get { protectedState.directValue.progressExecuter }
get { protectedState.wrappedValue.progressExecuter }
set { protectedState.write { $0.progressExecuter = newValue } }
}

private var successExecuter: Executer<SessionManager>? {
get { protectedState.directValue.successExecuter }
get { protectedState.wrappedValue.successExecuter }
set { protectedState.write { $0.successExecuter = newValue } }
}

private var failureExecuter: Executer<SessionManager>? {
get { protectedState.directValue.failureExecuter }
get { protectedState.wrappedValue.failureExecuter }
set { protectedState.write { $0.failureExecuter = newValue } }
}

private var completionExecuter: Executer<SessionManager>? {
get { protectedState.directValue.completionExecuter }
get { protectedState.wrappedValue.completionExecuter }
set { protectedState.write { $0.completionExecuter = newValue } }
}

private var controlExecuter: Executer<SessionManager>? {
get { protectedState.directValue.controlExecuter }
get { protectedState.wrappedValue.controlExecuter }
set { protectedState.write { $0.controlExecuter = newValue } }
}

Expand All @@ -225,7 +225,7 @@ public class SessionManager {
autoreleaseFrequency: .workItem)) {
let bundleIdentifier = Bundle.main.bundleIdentifier ?? "com.Daniels.Tiercel"
self.identifier = "\(bundleIdentifier).\(identifier)"
protectedState = Protector(
protectedState = Protected(
State(logger: logger ?? Logger(identifier: "\(bundleIdentifier).\(identifier)", option: .default),
configuration: configuration)
)
Expand Down Expand Up @@ -792,7 +792,7 @@ extension SessionManager {

// canceled
if status == .willCancel {
let succeededTasksCount = protectedState.directValue.taskMapper.values.count
let succeededTasksCount = protectedState.wrappedValue.taskMapper.values.count
if tasks.count == succeededTasksCount {
status = .canceled
executeControl()
Expand Down
46 changes: 23 additions & 23 deletions Sources/General/Task.swift
Expand Up @@ -98,35 +98,35 @@ public class Task<TaskType>: NSObject, Codable {
}


internal let protectedState: Protector<State>
internal let protectedState: Protected<State>

internal var session: URLSession? {
get { protectedState.directValue.session }
get { protectedState.wrappedValue.session }
set { protectedState.write { $0.session = newValue } }
}

internal var headers: [String: String]? {
get { protectedState.directValue.headers }
get { protectedState.wrappedValue.headers }
set { protectedState.write { $0.headers = newValue } }
}

internal var verificationCode: String? {
get { protectedState.directValue.verificationCode }
get { protectedState.wrappedValue.verificationCode }
set { protectedState.write { $0.verificationCode = newValue } }
}

internal var verificationType: FileChecksumHelper.VerificationType {
get { protectedState.directValue.verificationType }
get { protectedState.wrappedValue.verificationType }
set { protectedState.write { $0.verificationType = newValue } }
}

internal var isRemoveCompletely: Bool {
get { protectedState.directValue.isRemoveCompletely }
get { protectedState.wrappedValue.isRemoveCompletely }
set { protectedState.write { $0.isRemoveCompletely = newValue } }
}

public internal(set) var status: Status {
get { protectedState.directValue.status }
get { protectedState.wrappedValue.status }
set {
protectedState.write { $0.status = newValue }
if newValue == .willSuspend || newValue == .willCancel || newValue == .willRemove {
Expand All @@ -139,18 +139,18 @@ public class Task<TaskType>: NSObject, Codable {
}

public internal(set) var validation: Validation {
get { protectedState.directValue.validation }
get { protectedState.wrappedValue.validation }
set { protectedState.write { $0.validation = newValue } }
}

internal var currentURL: URL {
get { protectedState.directValue.currentURL }
get { protectedState.wrappedValue.currentURL }
set { protectedState.write { $0.currentURL = newValue } }
}


public internal(set) var startDate: Double {
get { protectedState.directValue.startDate }
get { protectedState.wrappedValue.startDate }
set { protectedState.write { $0.startDate = newValue } }
}

Expand All @@ -159,7 +159,7 @@ public class Task<TaskType>: NSObject, Codable {
}

public internal(set) var endDate: Double {
get { protectedState.directValue.endDate }
get { protectedState.wrappedValue.endDate }
set { protectedState.write { $0.endDate = newValue } }
}

Expand All @@ -169,7 +169,7 @@ public class Task<TaskType>: NSObject, Codable {


public internal(set) var speed: Int64 {
get { protectedState.directValue.speed }
get { protectedState.wrappedValue.speed }
set { protectedState.write { $0.speed = newValue } }
}

Expand All @@ -179,12 +179,12 @@ public class Task<TaskType>: NSObject, Codable {

/// 默认为url的md5加上文件扩展名
public internal(set) var fileName: String {
get { protectedState.directValue.fileName }
get { protectedState.wrappedValue.fileName }
set { protectedState.write { $0.fileName = newValue } }
}

public internal(set) var timeRemaining: Int64 {
get { protectedState.directValue.timeRemaining }
get { protectedState.wrappedValue.timeRemaining }
set { protectedState.write { $0.timeRemaining = newValue } }
}

Expand All @@ -193,38 +193,38 @@ public class Task<TaskType>: NSObject, Codable {
}

public internal(set) var error: Error? {
get { protectedState.directValue.error }
get { protectedState.wrappedValue.error }
set { protectedState.write { $0.error = newValue } }
}


internal var progressExecuter: Executer<TaskType>? {
get { protectedState.directValue.progressExecuter }
get { protectedState.wrappedValue.progressExecuter }
set { protectedState.write { $0.progressExecuter = newValue } }
}

internal var successExecuter: Executer<TaskType>? {
get { protectedState.directValue.successExecuter }
get { protectedState.wrappedValue.successExecuter }
set { protectedState.write { $0.successExecuter = newValue } }
}

internal var failureExecuter: Executer<TaskType>? {
get { protectedState.directValue.failureExecuter }
get { protectedState.wrappedValue.failureExecuter }
set { protectedState.write { $0.failureExecuter = newValue } }
}

internal var completionExecuter: Executer<TaskType>? {
get { protectedState.directValue.completionExecuter }
get { protectedState.wrappedValue.completionExecuter }
set { protectedState.write { $0.completionExecuter = newValue } }
}

internal var controlExecuter: Executer<TaskType>? {
get { protectedState.directValue.controlExecuter }
get { protectedState.wrappedValue.controlExecuter }
set { protectedState.write { $0.controlExecuter = newValue } }
}

internal var validateExecuter: Executer<TaskType>? {
get { protectedState.directValue.validateExecuter }
get { protectedState.wrappedValue.validateExecuter }
set { protectedState.write { $0.validateExecuter = newValue } }
}

Expand All @@ -237,7 +237,7 @@ public class Task<TaskType>: NSObject, Codable {
self.cache = cache
self.url = url
self.operationQueue = operationQueue
protectedState = Protector(State(currentURL: url, fileName: url.tr.fileName))
protectedState = Protected(State(currentURL: url, fileName: url.tr.fileName))
super.init()
self.headers = headers
}
Expand Down Expand Up @@ -272,7 +272,7 @@ public class Task<TaskType>: NSObject, Codable {
url = try container.decode(URL.self, forKey: .url)
let currentURL = try container.decode(URL.self, forKey: .currentURL)
let fileName = try container.decode(String.self, forKey: .fileName)
protectedState = Protector(State(currentURL: currentURL, fileName: fileName))
protectedState = Protected(State(currentURL: currentURL, fileName: fileName))
cache = decoder.userInfo[.cache] as? Cache ?? Cache("default")
operationQueue = decoder.userInfo[.operationQueue] as? DispatchQueue ?? DispatchQueue(label: "com.Tiercel.SessionManager.operationQueue")
super.init()
Expand Down

0 comments on commit 4b35a98

Please sign in to comment.