Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Ticket #28 (new defect)

Opened 13 years ago

Last modified 13 years ago

syncExec uses the wrong thread

Reported by: torhu Assigned to: doob
Priority: major Milestone:
Component: DWT-Win Version:
Keywords: Cc: torhu@yahoo.com

Description

This is with current tip of DWT2 for Windows (119:d00e8db0a568), using DMD 2.052.

When syncExec is run from a different thread than the main one, it tries to run the Runnable argument in that thread. It should use the main thread. I'm guessing the switch to thread-local by default caused this bug, but I haven't debugged it enough to be sure.

Test case below, in case anyone wants to look into this. It prints "secondary", correct output would be "main".

module test;
import std.stdio;
import core.thread;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Event;

import java.lang.all;

void f()
{
    Display.getDefault().syncExec(dgRunnable({
        writeln("in thread: ", core.thread.Thread.getThis().name);
    }));
}

public static void main (String [] args) {
    Display display = new Display ();
    Shell shell = new Shell (display);
    shell.setSize(200, 200);
    shell.setLayout(new FillLayout);
    Button button = new Button(shell, SWT.PUSH);
    button.setText("Click here");    

    button.addListener(SWT.Selection, new class Listener {
        void handleEvent(Event event)
        {
            core.thread.Thread.getThis().name = "main";
            auto t = new core.thread.Thread(&f);
            t.name = "secondary";
            t.start();
        }});
    shell.open ();
    while (!shell.isDisposed ()) {
        if (!display.readAndDispatch ()) display.sleep ();
    }
    display.dispose ();
}

Change History

06/16/11 22:39:37 changed by torhu

Found the problem.

Display has a Default member that is static, and needs to be __gshared.

In my own (discontinued) DWT2 port, I've done it like this:

    /* Multiple Displays */
    static mixin(GSHARED(`Display Default;`));
    static mixin(GSHARED(`Display [] Displays;`));

GSHARED looks like this, in java.lang.util:

version(D_Version2){
    string GSHARED(string s) { return "__gshared " ~ s; }
} else {
    String GSHARED(String s) { return s; }
}

There's gshared defined in 'offical' DWT2 too, but it contains an extra colon that looks a bit curious. It's not used anywhere.

There's probably a bunch of other places that need the same treatment.