Aliases to mutable thread-local data not allowed

mark mark at qtrac.eu
Tue Mar 10 08:13:19 UTC 2020


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;
     }
}

And I want to populate an AA of them:

Deb[string] debForName;

This takes 1.5 sec which is too slow.

So now I'm trying to read the files concurrently:

private struct DoneMessage {}

void initialize() { // main thread (some code elided)
     Tid[] tids;
     try {
         foreach (string filename; dirEntries(PATH_PATTERN, 
SpanMode.shallow))
             tids ~= spawn(&readPackageFile, thisTid, filename);
         auto jobs = tids.length;
         while (jobs) {
             receive(
                 (Deb deb) { debForName[deb.name] = deb; },
                 (DoneMessage m) { jobs--; }
             );
         }
     } catch (FileException err) {
         stderr.writeln("failed to read packages: ", err);
     }
}

// This is called once per child thread and calls send() 1000s of 
times to
// return Deb structs, finally sending DoneMessage.
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
     } catch (FileException err) {
         stderr.writeln(err);
     }
     send(parentTid, DoneMessage());
}

Unfortunately, I can't send Debs:

src/model.d(71,30): Error: template std.concurrency.spawn cannot 
deduce function from argument types !()(void delegate(Tid 
parentTid, string filename), Tid, string), candidates are:
/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/../import/std/concurrency.d(460,5):        spawn(F, T...)(F fn, T args)
   with F = void delegate(Tid, string),
        T = (Tid, string)
   must satisfy the following constraint:
        isSpawnable!(F, T)
src/model.d(72,13): Warning: statement is not reachable
src/model.d(73,13): Warning: statement is not reachable
src/model.d(79,13): Warning: statement is not reachable
src/model.d(72,13): Warning: statement is not reachable
src/model.d(73,13): Warning: statement is not reachable
src/model.d(79,13): Warning: statement is not reachable
/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."
src/model.d(102,21):        instantiated from here: send!(Deb)
/home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/ldc2 failed with exit 
code 1.

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?


More information about the Digitalmars-d-learn mailing list