Aliases to mutable thread-local data not allowed

Simen Kjærås simen.kjaras at gmail.com
Tue Mar 10 10:02:16 UTC 2020


On Tuesday, 10 March 2020 at 08:13:19 UTC, mark wrote:
> I have this struct:
>
> struct Deb {
>     string name;
>     ...
>     Unit[string] tags; // set of tags
>
>     Deb dup() const {
>         Deb deb;
>         deb.name = name;
>         ...
>         foreach (key; tags.byKey)
>             deb.tags[key] = unit;
>         return deb;
>     }
> }


> void readPackageFile(Tid parentTid, string filename) { // (some 
> code elided)
>     try {
>         Deb deb;
>         auto file = File(filename);
>         foreach(lino, line; file.byLine.enumerate(1))
>             readPackageLine(parentTid, filename, lino, line, 
> deb);
>             // readPackageLine also calls send with same code 
> as AAA below
>         if (deb.valid)
>             send(parentTid, deb.dup); // AAA


> /home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/concurrency.d(625,5): Error: static assert:  "Aliases to mutable thread-local data not allowed."
>
> Is there any nice solution to this? Surely it is a common 
> pattern to read multiple files and create lots of data items to 
> be merged into a collection?

As the error message hints at, the problem is Deb may hold 
references to data that is shared with other objects on the 
thread from which it originates. Since you know this is not the 
case, even if the compiler can't prove it, you can safely cast 
your Deb to immutable:

     if (deb.valid)
         send(parentTid, cast(immutable)deb.dup);

In fact, even the .dup is unnecessary here, since no data is 
shared with other objects, so you can simply write 
send(parentTid, cast(immutable)deb);. (Note on this point: since 
you have not included all your code, it could be other parts 
create shared mutable state, in which case .dup is necessary, and 
if badly written may not be sufficient.

--
   Simen


More information about the Digitalmars-d-learn mailing list