D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4790 - Wrong code when updating struct member value from fiber
Summary: Wrong code when updating struct member value from fiber
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2010-09-02 20:31 UTC by David Simcha
Modified: 2010-09-03 16:22 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description David Simcha 2010-09-02 20:31:20 UTC
This is a test case produced from an experiment with converting opApply to ranges using fibers:

import core.thread, std.traits, std.range, std.stdio;

struct OpApplyToRange(Iterable) {
    Fiber fiber;
    ForeachType!Iterable _front;
    Iterable iterable;

    void doLoop() {
        stderr.writeln("_front's address from fiber:  ", &_front);
        foreach(elem; iterable) {
            stderr.writefln("Assigning %s to front", elem);
            _front = elem;
            stderr.writeln("_front has value ", _front);
            Fiber.yield();
            stderr.writeln("Resumed with value ", _front);
        }

        stderr.writeln("doLoop done.");
    }

    this(Iterable iterable) {
        this.iterable = iterable;
        fiber = new Fiber(&doLoop);
        fiber.call();
    }

    void popFront() {
        fiber.call();
    }
}

void main() {
    auto oar = OpApplyToRange!(int[])([1,2,3]);
    stderr.writeln("_front's address from main:  ", &oar._front);

    foreach(i; 0..3) {
        stderr.writeln("Calling fiber sees:  ", oar._front);
        oar.popFront();
    }
}

_front's address from fiber:  18FE34
Assigning 1 to front
_front has value 1
_front's address from main:  18FE24
Calling fiber sees:  1
Resumed with value 1
Assigning 2 to front
_front has value 2
Calling fiber sees:  1
Resumed with value 2
Assigning 3 to front
_front has value 3
Calling fiber sees:  1
Resumed with value 3
doLoop done.

Apparently the same variable somehow has a different address when viewed from the main thread vs. fron a fiber, leading to some rather interesting consequences, like updates made from the fiber not being visible in the main function. (??????????)
Comment 1 David Simcha 2010-09-03 16:22:15 UTC
(Slaps self in forehead.)  Duh, of course.  When I take the address of doLoop() it's taking the address of a stack variable.  Of course this isn't going to work.  It needs to be a class.