On Tuesday, 17 August 2021 at 11:05:09 UTC, JG wrote:
Hi

I have a program with two threads. One thread produces data that is put in a queue and then consumed by the other thread. I initially built a custom queue to do this, but thought this should have some standard solution in D? I looked at std.concurrency and thought that message passing could be used. However, the problem is that I get the following error.

Error: static assert: "Aliases to mutable thread-local data not allowed."

I am not sure how to solve this.

The error tells you what you can't do. You can do anything other than that. What you *should* do depends on what exactly you're trying to do. Here are some examples:

Sending shared mutable data:

```d
import std.concurrency, std.stdio, core.atomic;

void incr() {
    auto counts = receiveOnly!(shared(int)[]);
    foreach (ref n; counts)
        atomicOp!"+="(n, 1); // shared(int) can't just be +='d
    ownerTid.send(true);
}

void main() {
    shared(int)[] counts = [0, 0, 0]; // no issues passing this
    spawn(&incr).send(counts);
    receiveOnly!bool;
    writeln(counts);
}
```

Sending immutable data:

```d
import std.concurrency, std.stdio, std.typecons;

void greeter() {
    auto who = receiveOnly!(string);
    writeln("Hello, ", who);
}

void main() {
char[] who = "John".dup; // mutable&thread-local, can't be sent spawn(&greeter).send(who.idup); // create immutable copy to send
}
```

Sending scalar data:

```d
import std.concurrency, std.stdio;

__gshared int[3] counts;

void incr() {
    auto indexes = receiveOnly!(int, int);
    foreach (ref n; counts[indexes[0] .. indexes[1]])
        n++;
    ownerTid.send(true);
}

void main() {
    spawn(&incr).send(1, 2);
    receiveOnly!bool;
    writeln(counts);
}
```

Reply via email to