[Issue 20484] Regression: runtime cannot handle shared(AA)

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Feb 18 21:54:29 UTC 2020


https://issues.dlang.org/show_bug.cgi?id=20484

ZombineDev <petar.p.kirov at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |petar.p.kirov at gmail.com

--- Comment #1 from ZombineDev <petar.p.kirov at gmail.com> ---
Shared AAs were never properly supported in druntime. I would say that before
the compiler was accepting invalid code. The reason is that the AA
implementation does not implement internal synchronization, and instead assumes
that all AA instances are thread-local.

The (pedantically) correct way to go is:
1. Keep using the `shared` type qualifier. It will prevent accidental mutation
of shared of non-internally synchronized data.
2. Use some form of external synchronization (mutex, read-write lock, etc.) to
ensure that there can be either a single writer or zero or more readers.
3. In a block of code where you have acquired exclusive write access (by means
of external synchronization), it's ok to cast the AA from type `shared(K[V])`
to `shared(K)[V]` or simply `K[V]` (*).
In a block where you have acquired read-access, you can safely cast from
`shared(K[V])` to `const(shared(K)[V])` or `const(K[V])` (*) 

(*) The distinction between shared(K)[V] and simply K[V] may be subtle, but
it's important and needs to be decided by the author of the code on a
case-by-case basis.

For example:

A) The type `int[][string]` allows mutation of both the AA (e.g. getting,
adding and removing int[] arrays) and each value (e.g. resizing the arrays and
changing each element).

B) With `shared(int[][string])` you can't do anything since druntime does not
(yet) implement internal synchronization of the AA implementation.

C) With `shared(int)[][string]` you can get, add and remove values from the AA,
and you can change the values by making them point to different arrays, but the
array elements can't be read/written to (without e.g. atomicLoad / atomicStore
/ cas)

D) `shared(int[])[string]` is kind of degenerate case between B) and C), but
pedantically speaking it can't work correctly, because to do so, the AA
implementation needs to use atomic load/store in order to guarantee the safe
mutation of values.

--


More information about the Digitalmars-d-bugs mailing list