SharedArrays: add `close`, zero dims when finalized (#62488)
some follow-ups to https://github.com/JuliaLang/julia/pull/60955/ .
agents were used for MWEs, tests, and docstring (edited / audited by
me), but the suggested fix is mine
basically, some tests were still flaky, observed in e.g.
[1](https://buildkite.com/organizations/julialang/pipelines/julia-pr/builds/686/jobs/019f8ab8-95ef-4470-8d3c-976fa48188a4/log),
[2](https://buildkite.com/organizations/julialang/pipelines/julia-pr/builds/717/jobs/019f8c91-a575-4afe-b28c-19c8b8075849/log),
[3](https://buildkite.com/organizations/julialang/pipelines/julia-pr/builds/720/jobs/019f8ca0-1a87-44ec-89f0-bb0c2a62adf1/log)
this was because the tests called `finalize(S)` on the host, then
`@everywhere GC.gc(true)` on the remotes, which is racy with `rm`. the
design of `unshare!` is intended to ensure that only a single GC round
is needed, but if we were to fix this but just adding `unshare!` it to
`fn` and `fn2` in the tests here, we'd _still_ have to add something
like `S = nothing` or `Mmap.munmap!(sdata(S))` then `GC.gc()` on the
host. clearly, this is hard to remember & use correctly, so I propose
`Base.close` handle this for the user.
a note for reviewers about the scary warning of `UB` in `unshare!`, this
was already a failure mode available if the user calls `truncate` on the
mapped file and then tries to access the shared data. I'm not sure it is
reasonable to expect perfect robustness under these kinds of scenarios.
the `S.dims = ntuple(d->0,N)` change is somewhat drive-by, but fixes
this OOB access existing on all previous versions
```julia
julia> using SharedArrays
julia> S = SharedArray{Int}(100, 100); fill!(S, 42); finalize(S)
julia> S[631:640]
10-element Vector{Int64}:
564049465049088
167
49
4294967302
1099511627788
281474993487873
72057598332895488
144679237540970496
576152699863553
```
cc @BioTurboNick
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Codex <codex@openai.com>