Cannot use Glibc.stdout/stderr with Concurrency (error: reference to var 'stderr' is not concurrency-safe because it involves shared mutable state)
Opened this issue · 6 comments
Description
Getting a compiler error when using Glibc.stdout/stderr with Concurrency
error: reference to var 'stderr' is not concurrency-safe because it involves shared mutable state
Reproduction
import Glibc
Task { fputs("hello", stderr) }
Expected behavior
compiles fine
Environment
6.0.2
Additional information
No response
any updates ?
ubuntu swift 6.0.3
// GlibC Linux platforms
import Glibc
private let stdoutLock = NSLock()
nonisolated(unsafe)
func configureStdout() {
stdoutLock.lock()
defer { stdoutLock.unlock() }
setbuf(stdout, nil)
}
configureStdout()
I've tried everything, nothing works
error: reference to var 'stdout' is not concurrency-safe because it involves shared mutable state
@nerzh For now, use
@preconcurrency import Glibc
and it'll work just fine
I suspect I'm missing something, but switching adding @preconcurrency
doesn't seem to be working for me:
#if os(Linux)
@preconcurrency import Glibc
#else
import Darwin.C
#endif
This still leaves me with:
58:20: error: reference to var 'stdout' is not concurrency-safe because it involves shared mutable state
56 | print("\r\(message): \(percentage)% (\(progress.completedUnitCount) / \(progress.totalUnitCount))",
57 | terminator: "")
58 | fflush(stdout)
| `- error: reference to var 'stdout' is not concurrency-safe because it involves shared mutable state
59 | }
60 | }
Which is a little confusing. I imagine I'm holding it wrong.
@jbmorley Well hello friend! Are you maybe also import Foundation
or something else? The @preconcurrency import Glibc
needs to come before anything else is importing Glibc
without @preconcurrency
.
See some issues/PRs here:
- swiftlang/swift-foundation#1175
- swiftlang/swift-format#933
- #79414
- swiftlang/swift-corelibs-foundation#5170
Essentially, you need to put @preconcurrency import Glibc
(and similar) as the very first import in all your files that require it to make sure it gets imported first with @preconcurrency
. Needless to say this is silly and needs fixing in Swift.
@weissi Hi! 👋🏻
Thanks for taking the time to give me some more thoughts. Turns out I was indeed also importing Foundation. I'd put the Glibc import above everything else just in case, but at no point did it occur to me that Foundation would also be importing Glibc. Of course it is. 🤦🏻
Oh well. All working now! Thank you again.