Pointer across threads

Chris via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Nov 4 06:46:49 PST 2014


On Tuesday, 4 November 2014 at 14:36:19 UTC, Chris wrote:
> On Tuesday, 4 November 2014 at 14:01:16 UTC, anonymous wrote:
>> On Tuesday, 4 November 2014 at 12:47:11 UTC, Chris wrote:
>>> The following
>>>
>>> struct DATA {
>>> short* data;
>>> size_t len;
>>> }
>>>
>>> // data and len are provided by a C function
>>> // ...
>>> auto data = mymodule.getSpeechData();
>>> // cast to immutable, because of concurrency
>>> immutable short* tmp = cast(immutable)(data.data);
>>> auto proc = spawn(&processData, thisTid);
>>> send(processData, tmp, data.len);
>>>
>>> However, processData never receives "tmp". Is this because 
>>> tmp and data.data are still pointing to the same address? If 
>>> this is the case, why doesn't the compiler warn me? Or is it 
>>> something else (pointer not visible across threads?).
>>>
>>> Is there a work around? (I wanted to avoid having to convert 
>>> short* to short[] and .idup it.)
>>
>> Please provide complete test cases. It makes it way easier for
>> others to help.
>>
>> One thing I noticed is that receiving immutable(short*) doesn't
>> work. Instead, it has to be immutable(short)* on the receiving
>> end. This is because immutable(T*) is automatically converted 
>> to
>> immutable(T)* on function calls. And apparently receive's
>> matching mechanism is inconveniently literal.
>
> Ah, thanks a lot, that was it! It has to be immutable(short)* 
> on the receiving end, now it works.
>
> receive (
>   (immutable(short)* data, size_t len) {
>    //...
> });
>
> It is indeed inconveniently literal, but I guess there's a 
> reason for it.
>
> I'm still curious, though, how D handles this internally, 
> because data.data is still mutable while the other reference to 
> the same address (tmp) is not. What if I change data.data while 
> the other thread is being executed?
>

Just tested it.

writeln(data.data[0]);
data.data[0] = -11;
send(play, tmp, data.len);
writeln(tmp[0]);
//
receive (
    (immutable(short)* data, size_t len) {
     writeln(data[0];
});

prints
0     // original value
-11   // tmp
-11  // data in the other thread

Is this behavior intended?


More information about the Digitalmars-d-learn mailing list