How to work around the infamous dual-context when using delegates together with std.parallelism

Christian Köstlin christian.koestlin at gmail.com
Thu May 27 12:47:06 UTC 2021


On 2021-05-27 13:11, sighoya wrote:
> On Thursday, 27 May 2021 at 09:58:40 UTC, Christian Köstlin wrote:
>> I have this small program here
>>
>> test.d:
>> ```
>> import std;
>> string doSomething(string[] servers, string user) {
>>     return user ~ servers[0];
>> }
>> void main() {
>>     auto servers = ["s1", "s2", "s3"];
>>     auto users = ["u1", "u2", "u3"];
>>     writeln(map!(user => servers.doSomething(user))(users));
>>     writeln(taskPool.amap!(user => servers.doSomething(user))(users));
>> }
>> ```
> 
> 
> 
> I think it relates to https://issues.dlang.org/show_bug.cgi?id=5710
> 
> The reason is that amap requires a this pointer of type TaskPool and a 
> context pointer to the closure which belongs to main, at least because 
> it requires servers. Having both isn't possible due to problems in non 
> DMD compilers.
> 
> If you rewrite it more statically:
> ```D
> string doSomething(string[] servers, string user) {
>      return user ~ servers[0];
> }
> 
> string closure(string user)
> {
>      return servers.doSomething(user);
> }
> auto servers = ["s1", "s2", "s3"];
> int main()
> {
>      auto users = ["u1", "u2", "u3"];
>      writeln(map!(user => servers.doSomething(user))(users));
>      writeln(taskPool.amap!(closure)(users));
>      return 0;
> }
> ```
> 
> PS: Just enable markdown if you want to highlight D code
On a second not I needed to make server __gshared in my real program, as 
otherwise its a thread local variable (in the small demo program, this 
did not occur, I guess because the parallel operations we're too fast).

Kind regards,
Christian


More information about the Digitalmars-d-learn mailing list