Re: [Vala] Combining async methods with external processes



On 20 November 2010 20:59, James Moschou <james moschou gmail com> wrote:
You can attach the .callback to any event source in the same way. So e.g.
when data arrive from the process or the child terminates etc.

But it's easy to wrap it in one. Just spawn_async_with_pipes and arrange the
.callback to be called when results are available and yield.

I think I got this working, it's compiling OK and it runs as expected
up until the last task is completed. But then it segfaults on some of
the generated C code. I'll try and make a test case later, as the
actual code is fairly convoluted.

Cheers
James


Here's an incredibly pared back version of what I have:


class Task : Object {
    Pid _pid;
    Source _source;
    public async void run_async () {
        try {
            Process.spawn_async_with_pipes (null,
                                            {"whois", "www.google.com"},
                                            null,
                                            SpawnFlags.SEARCH_PATH |
SpawnFlags.DO_NOT_REAP_CHILD,
                                            null,
                                            out _pid,
                                            null,
                                            null,
                                            null);

            _source = new GLibFixes.ChildWatchSource (_pid);
            _source.attach (null);
            _source.set_callback (run_async.callback);
            yield;
        }
        catch (Error error) {
            stderr.printf ("%s\n", error.message);
        }
        Process.close_pid (_pid);
    }
}

int main (string[] args) {
    Task task = new Task ();
    task.run_async.begin ();

    new MainLoop ().run ();
    return 0;
}


There's a problem one of the GLib bindings so you also need:

[CCode (cprefix = "G", lower_case_cprefix = "g_", cheader_filename =
"glib.h", gir_namespace = "GLib", gir_version = "2.0")]
namespace GLibFixes {
        public class ChildWatchSource : GLib.Source {
                public ChildWatchSource (GLib.Pid pid);
        }
}


Compile with:

valac test.vala fixes.vapi --pkg gio-2.0


It executes the process normally, but then segfaults. I'm not sure if
I'm attaching the callback properly.

Cheers
James



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]