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-11647] Swift 5.1 on Linux: Regression in OperationQueue concurrency #614

Open
swift-ci opened this issue Oct 21, 2019 · 2 comments
Open

[SR-11647] Swift 5.1 on Linux: Regression in OperationQueue concurrency #614

swift-ci opened this issue Oct 21, 2019 · 2 comments

Comments

@swift-ci
Copy link

@swift-ci swift-ci commented Oct 21, 2019

Previous ID SR-11647
Radar None
Original Reporter freak4pc (JIRA User)
Type Bug
Environment

Swift 5.1.1 latest Docker image

Additional Detail from JIRA
Votes 0
Component/s Foundation, libdispatch
Labels Bug, 5.1Regression
Assignee None
Priority Medium

md5: 4aa6a76a0b5ee28f3059851ef77c1f74

relates to:

  • SR-11864 Availability warnings in dead code paths

Issue Description:

We've bumped into an interesting regression in RxSwift's OperationQueueScheduler that wraps OperationQueue, specifically under Linux. It seems concurrency is broken or hangs.

The full issue is here:
ReactiveX/RxSwift#2077 (comment)

I was able to reduce the issue using only OperationQueue, without Rx:

import Foundation

let condition = NSCondition()
let sema = DispatchSemaphore(value: 0)
var writtenStarted = 0
var writtenEnded = 0
var events = [String]()
var lock = NSLock()

func performLocked(_ action: () -> Void) {
    lock.lock()
    action()
    lock.unlock()
}

let concurrent = {
    performLocked {
        print("Started")
        events.append("Started")
    }

    condition.lock()
    writtenStarted += 1
    condition.signal()
    while writtenStarted < 2 {
        condition.wait()
    }
    condition.unlock()

    performLocked {
        print("Ended")
        events.append("Ended")
    }

    condition.lock()
    writtenEnded += 1
    condition.signal()
    while writtenEnded < 2 {
        condition.wait()
    }
    condition.unlock()
    sema.signal()
}

let op1 = BlockOperation(block: concurrent)
let op2 = BlockOperation(block: concurrent)

let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 8

operationQueue.addOperation(op1)
operationQueue.addOperation(op2)
sema.wait()

Running the following code on macOS (in Swift 5.1 as well) or Linux with Swift 5.0 yields:

$ swift regression.swift
Started
Started
Ended
Ended

Running it under Linux with Swift 5.1:

$ swift -v
Swift version 5.1.1 (swift-5.1.1-RELEASE)

$ swift regression.swift
Started
-> At this point the process hangs and never completes

This seems to be an open regression in Swift 5.1 under Linux, but happy for any feedback or to provide any additional information.

@swift-ci
Copy link
Author

@swift-ci swift-ci commented Mar 4, 2020

Comment by Shai Mishali (JIRA)

Wanted to note this is still happening on the last version of Swift on Linux.

@weissi
Copy link
Member

@weissi weissi commented Mar 10, 2021

Can confirm that this is still happening on 5.3.3. Running this in a loop gave me

Started
Started
Ended
Ended
Started
Started
Ended
Ended
bash: line 1:   136 Segmentation fault      swift test.swift
johannes:/tmp

See the segfault

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants