Sign up

How to use threads?

Hello I have to use parallel tasks for my application.
This involves creating a command line process and parsing a file created by the said process every half a second.

Before starting the gtk loop, I initiated GDK:

    // main.d
    import gdk.Threads : threadsInit;

    threadsInit();
    return app.run(args);

Now before and after running the parallel process I'm entering and leaving the thread:

// ui.d
trigger.addOnClicked(delegate void(Button _) {
            deactivateInputs();
            scope (success)
                activateInputs();
            progressBoxRevealer.setRevealChild(true);

            auto sourceFileName = fcb.getFilename();
            auto deviceName = parseDeviceName(deviceCombo.getActiveText());
            import gdk.Threads : threadsEnter, threadsLeave;

            threadsEnter();

            auto ddCall = new Calldd(sourceFileName, deviceName);
            import std.parallelism : task, Task;

            auto proc = task(&ddCall.dd);
            proc.executeInNewThread();

            while ((!proc.done))
            {
                import glib.Timeout : Timeout;
                import gtkc.gtktypes : GPriority;

                auto timeout = new Timeout(500, delegate bool() {
                    auto percentage = ddCall.parse();

                    if (percentage == 0.0)
                    {
                        progress.pulse();
                    }
                    else if (percentage == 100.0)
                    {
                        return false;
                    }
                    else
                    {
                        progress.setFraction(percentage);
                    }
                    return true;

                }, GPriority.HIGH);
            }
            threadsLeave();

        });
    }

Yet the whole app, in fact freezes. Any hint?
If you are interested the whole project (pretty small) is here
https://gitlab.com/9898287/nixwriter/tree/master/source

Re: How to use threads?

On 19-11-2018 21:51, adnan wrote:

Hello I have to use parallel tasks for my application.
This involves creating a command line process and parsing a file created by the said process every half a second.

On the GDK side the thread init/enter/leave functions are deprecated,
and all UI calls into gtk should be made from the UI thread.

In that case you would use core.thread from druntime for your threading,
and setup a glib.Timeout to update the UI based on some shared state.

I see you are creating a new Timeout inside the loop, while glib.Timeout
will be called from the GTK mainloop, with at least the timeout between
calls, until it returns true. So you wouldn't want to do this in a loop.

Re: How to use threads?

On Mon, 19 Nov 2018 22:25:39 +0100, Mike Wey wrote:

On 19-11-2018 21:51, adnan wrote:

Hello I have to use parallel tasks for my application.
This involves creating a command line process and parsing a file created by the said process every half a second.

On the GDK side the thread init/enter/leave functions are deprecated,
and all UI calls into gtk should be made from the UI thread.

In that case you would use core.thread from druntime for your threading,
and setup a glib.Timeout to update the UI based on some shared state.

I see you are creating a new Timeout inside the loop, while glib.Timeout
will be called from the GTK mainloop, with at least the timeout between
calls, until it returns true. So you wouldn't want to do this in a loop.

Okay, I'm trying to achieve this with

        trigger.addOnClicked(delegate void(Button _) {
            deactivateInputs();

            progressBoxRevealer.setRevealChild(true);

            auto sourceFileName = fcb.getFilename();
            auto deviceName = parseDeviceName(deviceCombo.getActiveText());

            auto ddCall = new Calldd(sourceFileName, deviceName);
            import std.parallelism : task;

            auto proc = task(&ddCall.dd);
            proc.executeInNewThread();

            import glib.Timeout : Timeout;
            import gtkc.gtktypes : GPriority;

            auto timeout = new Timeout(500, delegate bool() {
                auto percentage = ddCall.parse();

                if (percentage == 0.0)
                {
                    progress.pulse();
                }
                else if (percentage == 100.0)
                {
                    activateInputs();

                    return false;
                }
                else
                {
                    debug
                    {
                        writefln("Percentage: %s", percentage);
                    }
                    progress.setFraction(percentage);
                }
                return true;

            }, GPriority.HIGH);
        });

However, once the the proc starts in a new thread and when the inputs are set insensitive, the timeout doesn't seem to update? I put a writefln in debug mode too, it prints nothing. And the timeout keeps running forever. What could be causing this?

Re: How to use threads?

On Mon, 19 Nov 2018 22:20:48 GMT, adnan wrote:

On Mon, 19 Nov 2018 22:25:39 +0100, Mike Wey wrote:

On 19-11-2018 21:51, adnan wrote:

Hello I have to use parallel tasks for my application.
This involves creating a command line process and parsing a file created by the said process every half a second.

On the GDK side the thread init/enter/leave functions are deprecated,
and all UI calls into gtk should be made from the UI thread.

In that case you would use core.thread from druntime for your threading,
and setup a glib.Timeout to update the UI based on some shared state.

I see you are creating a new Timeout inside the loop, while glib.Timeout
will be called from the GTK mainloop, with at least the timeout between
calls, until it returns true. So you wouldn't want to do this in a loop.

Okay, I'm trying to achieve this with

        trigger.addOnClicked(delegate void(Button _) {
            deactivateInputs();

            progressBoxRevealer.setRevealChild(true);

            auto sourceFileName = fcb.getFilename();
            auto deviceName = parseDeviceName(deviceCombo.getActiveText());

            auto ddCall = new Calldd(sourceFileName, deviceName);
            import std.parallelism : task;

            auto proc = task(&ddCall.dd);
            proc.executeInNewThread();

            import glib.Timeout : Timeout;
            import gtkc.gtktypes : GPriority;

            auto timeout = new Timeout(500, delegate bool() {
                auto percentage = ddCall.parse();

                if (percentage == 0.0)
                {
                    progress.pulse();
                }
                else if (percentage == 100.0)
                {
                    activateInputs();

                    return false;
                }
                else
                {
                    debug
                    {
                        writefln("Percentage: %s", percentage);
                    }
                    progress.setFraction(percentage);
                }
                return true;

            }, GPriority.HIGH);
        });

However, once the the proc starts in a new thread and when the inputs are set insensitive, the timeout doesn't seem to update? I put a writefln in debug mode too, it prints nothing. And the timeout keeps running forever. What could be causing this?

nvm fixed it. my parser wasn't right.