Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-14283] [Concurrency]: Crash under getNextJobInQueue #56642

Closed
jshier opened this issue Feb 28, 2021 · 2 comments
Closed

[SR-14283] [Concurrency]: Crash under getNextJobInQueue #56642

jshier opened this issue Feb 28, 2021 · 2 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. concurrency Feature: umbrella label for concurrency language features

Comments

@jshier
Copy link
Contributor

jshier commented Feb 28, 2021

Previous ID SR-14283
Radar rdar://problem/74876591
Original Reporter @jshier
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

macOS 11.2.2, 2020 iMac, Xcode 12.4, swift-DEVELOPMENT-SNAPSHOT-2021-02-24-a

Additional Detail from JIRA
Votes 0
Component/s
Labels Bug, Concurrency
Assignee @jshier
Priority Medium

md5: 49ddb9796102b1b373c4c43941ee6790

Issue Description:

The following program runs and completes the network request successfully but then crashes in `getNextJobInQueue` with the attached report.

actor Session {
    private(set) lazy var session = URLSession(configuration: .default, delegate: sessionDelegate, delegateQueue: nil)
    private(set) lazy var sessionDelegate = SessionDelegate(self)
    
    private(set) var requests: [URLSessionTask: DataRequest] = [:]
    
    func request() async throws -> DataRequest {
        let request = DataRequest()
        let task = await request.task(using: session)
        requests[task] = request
        task.resume()
        
        return request
    }
    
    func request(for task: URLSessionTask) -> DataRequest? {
        requests[task]
    }
}

actor SessionDelegate: NSObject {
    private weak var owner: Session?
    
    init(_ owner: Session) {
        self.owner = owner
    }
}

extension SessionDelegate: URLSessionTaskDelegate {
    @asyncHandler
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        await owner?.request(for: task)?.didComplete(error)
    }
}

extension SessionDelegate: URLSessionDataDelegate {
    @asyncHandler
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        await owner?.request(for: dataTask)?.didReceive(data)
    }
}

actor DataRequest {
    private(set) var data = Data()
    private(set) var error: Error?
    private var completion: ((Data, Error?) -> Void)?
    
    func task(using session: URLSession) -> URLSessionTask {
        session.dataTask(with: URLRequest(url: URL(string: "https://httpbin.org/get")!))
    }
    
    func didComplete(_ error: Error?) {
        self.error = error
        print("didComplete")
        completion?(data, self.error)
    }
    
    func didReceive(_ data: Data) {
        self.data.append(data)
    }
    
    func awaitCompletion() async throws -> Data {
        try await withUnsafeThrowingContinuation { continuation in
            self.completion = { data, error in
                if let error = error {
                    continuation.resume(throwing: error)
                } else {
                    continuation.resume(returning: data)
                }
            }
        }
    }
}

runAsyncAndBlock {
    let session = Session()
    do {
        let data = try await session.request().awaitCompletion()
        print(String(decoding: data, as: UTF8.self))
    } catch {
        print(error)
    }
}
@typesanitizer
Copy link

@swift-ci create

@jckarter
Copy link
Member

@kavon and I landed a couple of memory management fixes that appear to get this example working. If you give a go in the next snapshot, it should hopefully be working now.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. concurrency Feature: umbrella label for concurrency language features
Projects
None yet
Development

No branches or pull requests

3 participants