Bug 9122 – std.concurrency send() fails with multiple arrays

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2012-12-07T06:04:00Z
Last change time
2013-05-27T19:30:03Z
Assigned to
nobody
Creator
john.loughran.colvin
Depends on
10017
See also
http://d.puremagic.com/issues/show_bug.cgi?id=10017

Comments

Comment #0 by john.loughran.colvin — 2012-12-07T06:04:25Z
import std.concurrency; import std.stdio; void foo() { bool running = true; while(running) { receive( (immutable(double)[] a, immutable(double)[] b, int i) { writeln(a, b, i); }, (OwnerTerminated e) { running = false; } ); } } void main() { double[] a,b; a = [1.1]; b = [2.2]; int i= 3; auto tid = spawn(&foo); tid.send(a.idup, b.idup, i); } I get: core.exception.AssertError@ std/variant.d(277): target must be non-null
Comment #1 by david — 2013-01-03T04:44:21Z
This is probably related to issue 7069. The problem also occurs on structs like this: import std.concurrency, std.exception, std.stdio; struct Combined { string str1; string str2; bool status; } void main() { auto tid = spawn(&worker); Combined c = Combined("one", "two", false); tid.send(c); } void worker() { for (bool running = true; running; ) { receive( (Combined c) { writeln("Got ", c.str1, "\t", c.str2, "\t", c.status); }, (OwnerTerminated unused) { running = false; } ); } }
Comment #2 by david — 2013-01-03T05:51:35Z
Bumping importance. This issue makes it impossible for me to move to 2.061 because it breaks all my applications that use message passing for concurrency.
Comment #3 by mk — 2013-03-31T15:59:08Z
Code from comment #1 works for me in 32 bit, but I get the same error message ("target must be non-null") when the size of a message (Combined.sizeof) exceeds 24 bytes.
Comment #4 by zheny — 2013-04-19T10:02:44Z
Is anyone working on this issue?
Comment #5 by octavian.cacina — 2013-04-23T11:45:43Z
I hit this bug too as I wanted to send a structure. Martin Krejcirik was right about the size of the structure. As soon as the message to be sent exceeds 20 bytes (win32) it comes to the assert. I see that the problem is with the default generated opAssign for the struct Message in std.concurrency. This Message has a "Variant data" attribute that needs to be copied. I could reproduce the error like this: --- struct S { int p1, p2, p3, p4, p5, p6; } Variant v1 = S(); Variant v2; v2 = v1; // assert --- The Variant is defined like: alias VariantN!(maxSize!(creal, char[], void delegate())) Variant; so it has already a fixed size. The constructor can cope with the bigger size and will adjust, but the opAssign does not. I do not know if it is a bug that the constructor allows it or that the opAssign does not. A possible fix would be to add an opAssign operator to the Message structure: --- ref Message opAssign(Message rhs) { type = rhs.type; swap(data, rhs.data); return this; } ---
Comment #6 by code — 2013-05-14T20:07:55Z
(In reply to comment #5) > The Variant is defined like: > alias VariantN!(maxSize!(creal, char[], void delegate())) Variant; > so it has already a fixed size. The constructor can cope with the bigger size > and will adjust, but the opAssign does not. OpAssign moves the assigned value onto the heap so this is not the problem. https://github.com/D-Programming-Language/phobos/blob/c319b1578f28e00124d2f0c2a492790d01ca5159/std/variant.d#L545 Also the following code works correctly for me on 2.062. --- import std.variant, std.stdio; struct S { int p1, p2, p3, p4, p5, p6; } void main() { Variant v1 = S(1, 2, 3, 4, 5, 6); writeln(v1); Variant v2; writeln(v2); v2 = v1; // assert writeln(v2); } --- The bug seems to be in the handler for OpID.copyOut.
Comment #7 by octavian.cacina — 2013-05-14T23:54:37Z
(In reply to comment #6) > > Also the following code works correctly for me on 2.062. yes, here I have a wrong sample, the structure size must exceed 32bytes. The S should be: struct S { int[9] s; } See #10017 - Can not assign to a Variant another Variant holding a bigger structure I also made a pull request for it ( https://github.com/D-Programming-Language/phobos/pull/1281 ) but David Nadlinger wants to fix the fact that these Variant assignments trigger a reallocation even if there already is a heap value (comments in pull).
Comment #8 by david — 2013-05-27T18:10:07Z
Comment #9 by andrei — 2013-05-27T19:30:03Z