Re: Is it possible to modify shared struct array in a function.
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
Re: Is it possible to modify shared struct array in a function.
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
Re: Is it possible to modify shared struct array in a function.
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.
Re: Is it possible to modify shared struct array in a function.
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: [...] 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 `shared struct Metadata` should make it work. Turtles (shared) all the way down.
Re: Is it possible to modify shared struct array in a function.
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: I have a situation, where i want to modify a shared variable in a function. Something like below 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; } Compiler throws me error in last line for appending as below. "cannot append type Metadata to type shared(Metadata[])". Please let me know if there is a way to acheive this. Thanks, Sudhi 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
Re: Is it possible to modify shared struct array in a function.
On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi wrote: I have a situation, where i want to modify a shared variable in a function. Something like below 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; } Compiler throws me error in last line for appending as below. "cannot append type Metadata to type shared(Metadata[])". Please let me know if there is a way to acheive this. Thanks, Sudhi Works fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU