Skip to content

Cannot use Glibc.stdout/stderr with Concurrency (error: reference to var 'stderr' is not concurrency-safe because it involves shared mutable state) #77866

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

Open
weissi opened this issue Nov 28, 2024 · 6 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. concurrency Feature: umbrella label for concurrency language features input & output Area → standard library: Input & output Linux Platform: Linux standard library Area: Standard library umbrella

Comments

@weissi
Copy link
Contributor

weissi commented Nov 28, 2024

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

@weissi weissi added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Nov 28, 2024
@MaxDesiatov MaxDesiatov added concurrency Feature: umbrella label for concurrency language features Linux Platform: Linux standard library Area: Standard library umbrella input & output Area → standard library: Input & output and removed triage needed This issue needs more specific labels labels Nov 28, 2024
@nerzh
Copy link

nerzh commented Feb 26, 2025

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

@weissi
Copy link
Contributor Author

weissi commented Feb 27, 2025

@nerzh For now, use

@preconcurrency import Glibc

and it'll work just fine

@nerzh
Copy link

nerzh commented Feb 27, 2025

@weissi thank you for fast answer 🤝

@jbmorley
Copy link

@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.

@weissi
Copy link
Contributor Author

weissi commented Feb 28, 2025

@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:

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.

@jbmorley
Copy link

jbmorley commented Mar 1, 2025

@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.

Lukasa pushed a commit to apple/swift-nio that referenced this issue Mar 21, 2025
### Motivation:

The non-`Darwin` libcs don't have the correct concurrency annotations.
But due to these Swift bugs, it's important that the _first_ importer
uses `@preconcurrency`:

- swiftlang/swift#79414
- swiftlang/swift#77866

### Modifications:

Much like the Foundation (& corelibs) PRs such as
swiftlang/swift-foundation#1175 , use
`@preconcurrency import` for the non-`Darwin` libcs.

### Result:

Fewer bad warnings/errors in user code.
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 input & output Area → standard library: Input & output Linux Platform: Linux standard library Area: Standard library umbrella
Projects
None yet
Development

No branches or pull requests

4 participants