www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 13916] New: Nested std.concurrency.receive doesn't work

https://issues.dlang.org/show_bug.cgi?id=13916

          Issue ID: 13916
           Summary: Nested std.concurrency.receive doesn't work correctly
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: Phobos
          Assignee: nobody puremagic.com
          Reporter: yazan.dabain gmail.com

```
import std.concurrency;
import std.stdio;

// version = working;

void child()
{
  int i;
  while (true)
  {
    i = receiveOnly!int();
    ownerTid().send(i);
    ownerTid().send(i);
    writeln("2 messages sent");
  }
}

void main()
{
  Tid child = spawnLinked(&child);

  while (true)
  {
    int i;
    child.send(i);
    receive(                  // A
      (int x)
      {
        version (working) {}
        else
        {
          writeln("blocking until 2nd message is received");
          receiveOnly!int();        // B
          writeln("2nd message was received");
        }
      }
    );
    version (working)
    {
      writeln("blocking until 2nd message is received");
      receiveOnly!int();      // C
      writeln("2nd message was received");
    }
    writeln("one loop");
  }
}

```

In `version = working`, the program works as expected printing:
`2 messages sent
blocking until 2nd message is received
2nd message was received
one loop
2 messages sent
blocking until 2nd message is received
2nd message was received
one loop`
... and so on

With `version = working` commented out, instead of having the two receives in
series (A + C), receive (B) is used in the message handler of receive (A) (i.e
receive (B) is nested). Running the program on a multi-core CPU prints:
`2 messages sent
blocking until 2nd message is received`
and it hangs without reaching `2nd message was received`.
When running the same program using `taskset 0x01 ./test` (which limits the
CPUs that the program can run on to 1) the behavior becomes similar to the
working version for a while but it still hangs eventually.

--
Dec 30 2014