-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
ENV as a normal Dict: populate at boot, copy when spawning children #36494
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
Conversation
I'm ok with it in general, but I'm not quite sure we can do it in 1.x, since there's certainly packages relying on being able to modify |
There was a lot of concern in a recent discussion thread about the fact that modifying |
It's a problem, but somewhat tempered for the moment by threading being not very common and even when people use threading having these kinds of modifications happen mostly at load time. I'm just not sure we can do it now. At the very least, we'd need to survey existing packages and have a list of things that need to get fixed. |
the child process. This means that `ENV` cannot be used to communicate via the | ||
current proccess's environment with libraries. | ||
""" | ||
const ENV = Dict{String,String}() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you need a lock?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it were possible to lock on an arbitrary object, then I'd say it's the callers responsibility to do the locking, but that's not possible so I guess we either need an official ENV_LOCK
object or need to make this a threadsafe dict type, which I guess would therefore need to live in Base and might as well be exported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A thread-safe Dict would be useful for many use-cases in addition to this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, regarding being able to lock on arbitrary objects, this PR doesn't implement that directly but implements a struct that bundles objects and their locks together: #34400
This is a breaking change because, as discussed in #34726, modifying the process environment is the only way to communicate with some C libraries. I think we need to make the thread-safe version opt-in with something like |
I don't really have a dog in this fight: I neither particularly care about the libc thread safety issues, nor do I particularly care about C libraries that need to be communicated to via environment variables. I made this PR because I was looking at the relevant code and the upshot of the discussion in #34726 seemed to be that this was the best approach. So if people don't want this, feel free to close this PR. |
We could do a PkgEval run and fix the packages that break? |
I think there are three concurrency concerns:
(The first two points would be identical if we keep Note that using a lock is an OK solution for the first two points but rather terrible one for the last point. This is because On top of these complications, there is a concern of backward compatibility. I think the best approach is to just add a lock in the current
I think we are pretty sure that this is breaking. IIUC, Cairo.jl and Gtk.jl examples in #36440 (comment) using environment variables to configure external libraries. Even Also (it's not particularity criticizing your comment, @DilumAluthge), I think we need to remember that there are tons of private code that is invisible to PkgEval. I think PkgEval should primary be used to catch the breaking changes we missed in the review but not for breaking the backward compatibility promise on purpose (although I know there are exceptions). |
That's a good point. Fixing the PkgEval failures would not be sufficient in this case. |
Instead of modifying the process environment in-place, which is inherently thread-unsafe because of how most
libc
libraries are implemented, this changes theENV
global to be populated from the process environment at Julia's startup time and when starting a child process it populates the child's environment with a copy ofENV
so the process's environment is never modified.