www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.dwt - Bug in DWT's syncExec/asyncExec, or possibly DMD or std.thread

(Crossposted to digitalmars.D.dwt and digitalmars.D.bugs, since I'm not at all
sure where the bug is. Followup-To set to d.D.bugs.)

Take a look at the following code, showing a bug I originally ran into whilst
trying to get SWT snippet 56 (
http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet56.java
) to work with D and DWT:

--
private import
	std.string,
	std.thread,
	dwt.all;

pragma (lib, "dwt");
pragma (lib, "advapi32");
pragma (lib, "comctl32");
pragma (lib, "ole32");
pragma (lib, "uuid");
pragma (lib, "imm32_dwt");
pragma (lib, "msimg32_dwt");
pragma (lib, "usp10_dwt");
pragma (lib, "oleaut32_dwt");
pragma (lib, "oleacc_dwt");

void main() {
	Display     display = new Display();
	Shell       shell   = new Shell();
	shell.pack();
	shell.open();

uint i = 50;
uint j = 3;

	(new class Thread {
		int run() {
//uint i = 50;
			display.syncExec(new class Runnable {
				void run() {
					j = i;
				}
			});

			return 0;
		}
	}).start();

	while (!shell.isDisposed())
		if (!display.readAndDispatch())
			display.sleep();

	MessageBox.showMsg(format("%d", j));

	display.dispose();
}
--

The code creates a Thread which asks display.syncExec (or asyncExec - same
results) to set j = i. Since i is 50, j should also be 50 at the end. And, with
the above code, that's what happens.

However, if you uncomment the "uint i = 50" within the Thread's run() method, so
that j is set to that inner i, j ends up being 0 - not even 3, its original
value, but 0.

In this case, the issue can be worked around by setting the inner i to be static
or const, but in a more complex situation this is, of course, not possible.

Where's the bug, or am I doing something inherently wrong/unsafe?
May 26 2006