On Friday, February 8, 2019 4:27:44 AM MST Eduard Staniloiu via Digitalmars- d-learn wrote: > On Friday, 8 February 2019 at 06:55:15 UTC, Jerry wrote: > > On Friday, 8 February 2019 at 04:51:08 UTC, Sudhi wrote: > >> On Friday, 8 February 2019 at 04:30:23 UTC, Arun > >> > >> Chandrasekaran wrote: > >>> On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi wrote: > >>>> [...] > >>> > >>> Works fine for me with DMD64 D Compiler v2.083.1. > >>> https://run.dlang.io/is/RRM8GU > >> > >> My example code was wrong. Below is the right one. > >> > >> struct Company > >> { > >> > >> string name; > >> string location; > >> > >> } > >> > >> struct Racks > >> { > >> > >> int number; > >> int location; > >> > >> } > >> > >> struct Metadata > >> { > >> > >> string name; > >> Company[] companies; > >> Racks[] racks; > >> > >> } > >> > >> struct Item > >> { > >> > >> Metadata[] met; > >> int count; > >> > >> } > >> > >> shared (Item) item; > >> > >> void main() > >> { > >> > >> updateMetadata(); > >> > >> } > >> > >> void updateMetadata() > >> { > >> > >> Company company; > >> company.name = "Hello"; > >> company.location = "Bangalore"; > >> item.met.companies ~= company; > >> import std.stdio: writeln; > >> writeln(item); > >> > >> } > >> > >> https://run.dlang.io/is/iem0PY > > > > You have to cast away shared: > > > > auto loc_item = cast(Item) item; > > loc_item.met ~= m; > > item = cast(shared) loc_item; > > > > Just to be clear, this is not threadsafe and require a mutex if > > you do this other than as init in main. > > You do not need to cast away shared. You had a couple of issues > with your `updateMetadata()` function. > > First of, `met` is an array, so you need to index it: your code > `item.met.companies ~= company` becomes `item.met[0].companies ~= > company`. This will compile, but throw a range error because you > don't have any `Metadata` object in your `met` array. > > I have typed below the revised form of your function > > ``` > void updateMetadata() > { > // create a Company instance. This must be shared > shared Company company; > company.name = "Hello"; > company.location = "Bangalore"; > > // create a shared Metadata instance > shared Metadata m; > m.name = "m"; > > // append m to the array of meta > item.met ~= m; > // append the company to the array of companies, for a given > meta > item.met[0].companies ~= company; > > import std.stdio: writeln; > writeln(item); > } > ``` > > The working version is at https://run.dlang.io/is/RvRKrU > > Cheers, > Edi
Honestly, the fact that that code compiles is a bug. You're not supposed to be able to modify shared objects in a manner which isn't guaranteed to be atomic, because it's not thread-safe. The compiler catches it in a number of places, but there are many where it currently doesn't. But regardless of whether the compiler allows such mutation, a mutex (or similar protection mechanism) needs to be used in order to make the code thread-safe. - Jonathan M Davis