yield in vala and gio concurrency

By no means, I’m an expert in vala or gio. Infact, I’m just a beginner, but I have learned something while playing with vala which I want to record (for future reference). Here I’ll explain how Gio’s async framework works and how vala uses Gio beneath the tree.

Gio Async Framework:

Better to explain with an example,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define TEST_TYPE_GIO_ASYNC (test_gio_async_get_type())
typedef struct _TestGioAsync TestGioAsync;
typedef struct _TestGioAsyncClass TestGioAsyncClass;
typedef struct _TestGioAsyncPrivate TestGioAsyncPrivate;
struct _TestGioAsyncClass {
GObjectClass parent;
struct _TestGioAsyncPrivate {
gchar *something_to_say;
struct _TestGioAsync {
GObject parent_instance;
TestGioAsyncPrivate *priv;
enum {
static gpointer test_gio_async_parent_class = NULL;
GType test_gio_async_get_type(void) G_GNUC_CONST;
static void test_gio_async_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *spec) {
TestGioAsyncPrivate *priv = NULL;
switch(prop_id) {
priv->something_to_say = g_value_dup_string(value);
static void test_gio_async_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *spec) {
TestGioAsyncPrivate *priv = NULL;
switch(prop_id) {
g_value_set_string(value, priv->something_to_say);
static void test_gio_async_instance_init(TestGioAsync *self) {
self->priv = TEST_GIO_ASYNC_GET_PRIVATE(self);
static void test_gio_async_finalize(GObject *obj) {
TestGioAsyncPrivate *priv = NULL;
static void test_gio_async_class_init(TestGioAsyncClass *klass) {
test_gio_async_parent_class = g_type_class_peek_parent(klass);
g_type_class_add_private(klass, sizeof(TestGioAsyncPrivate));
G_OBJECT_CLASS(klass)->set_property = test_gio_async_set_property;
G_OBJECT_CLASS(klass)->get_property = test_gio_async_get_property;
G_OBJECT_CLASS(klass)->finalize = test_gio_async_finalize;
GType test_gio_async_get_type(void) {
static volatile gsize test_gio_async_type_id__volatile = 0;
if(g_once_init_enter(&test_gio_async_type_id__volatile)) {
static const GTypeInfo g_define_type_info = { sizeof(TestGioAsyncClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) test_gio_async_class_init,
(GClassFinalizeFunc) NULL,
(GInstanceInitFunc) test_gio_async_instance_init,
, GType test_gio_async_type_id = g_type_register_static(G_TYPE_OBJECT,
g_once_init_leave(&test_gio_async_type_id__volatile, test_gio_async_type_id);
return test_gio_async_type_id__volatile;
TestGioAsync* test_gio_async_new(void) {
return g_object_new(TEST_TYPE_GIO_ASYNC, NULL);
static gboolean test_gio_async_say_idle_func(gpointer user_data) {
TestGioAsync *self = (TestGioAsync *) user_data;
GSimpleAsyncResult *simple = g_object_get_data(G_OBJECT(self), "simple");
gchar *result = NULL;
g_object_get(G_OBJECT(self), "something_to_say", &result, NULL);
g_simple_async_result_set_op_res_gpointer(simple, result, g_free);
return FALSE;
void test_gio_async_say(TestGioAsync *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data) {
GSimpleAsyncResult *simple = g_simple_async_result_new(G_OBJECT(self),
g_simple_async_result_set_check_cancellable(simple, cancellable);
g_object_set_data(G_OBJECT(self), "simple", simple);
g_idle_add(test_gio_async_say_idle_func, self);
gchar* test_gio_async_say_finish(TestGioAsync *self,
GAsyncResult *res,
GError **error) {
GSimpleAsyncResult *simple = NULL;
g_return_val_if_fail(g_simple_async_result_is_valid(res, G_OBJECT(self), test_gio_async_say), NULL);
simple = (GSimpleAsyncResult *) res;
if(error) g_simple_async_result_propagate_error(simple, error);
return g_simple_async_result_get_op_res_gpointer(simple);
static void test_gio_async_say_cb(GObject *self, GAsyncResult *res, gpointer user_data) {
gchar *result = test_gio_async_say_finish(TEST_GIO_ASYNC(self), res, NULL);
GMainLoop *mainloop = (GMainLoop *) user_data;
g_print("%s\n", result);
int main(int argc, char *argv[]) {
TestGioAsync *test = test_gio_async_new();
GMainLoop *mainloop = g_main_loop_new(NULL, TRUE);
g_object_set(G_OBJECT(test), "something_to_say", "hello world", NULL);
test_gio_async_say(test, NULL, test_gio_async_say_cb, mainloop);
g_print("started saying..\n");
return 0;

view raw
hosted with ❤ by GitHub

Here, I have created a new GObject class called TestGioAsync with something_to_say property. I have implemented a simple async function called test_gio_async_say.  When called, test_gio_async_say will setup GSimpleAsync object, attach another function called test_gio_async_say_idle_func into GMainLoop’s next idle iteration and return.

Once test_gio_async_say_idle_func triggered, it takes the value from something_to_say property and put it into g_simple_async_result_set_op_res_pointer as op_res (which will be picked-up later) and completes the async transaction with g_simple_async_result_complete_in_idle which will call the test_gio_async_say_cb provided in test_gio_async_say in GMainLoop’s next idle iteration.

Once test_gio_async_say_cb triggered, it will call test_gio_async_say_finish which will simply return op_res which contains the value taken from something_to_say property.

Vala Async Framework:

This is the equivalent vala example for the above C example

#!/usr/bin/env vala
class Test.Async : GLib.Object {
public async string say(string sentence) {
return sentence;
public static int main(string[] args) {
Test.Async myasync = new Test.Async();
GLib.MainLoop mainloop = new GLib.MainLoop();
(obj, res) => {
string sentence = myasync.say.end(res);
print("%s\n", sentence);
return 0;

view raw
hosted with ❤ by GitHub

Vala async functions returns immediately whenever it reaches yield keyword, In this example, I have hooked this.say.callback into GMainLoop’s next idle iteration. In the next idle iteration, this.say will be called and will start execution exactly after the yield statement which will eventually trigger the anonymous lambda function provided in  this.say.begin with sentence as return value.

Once the lambda function triggered, it will call this.say.end which will return the sentence value to the lambda function.

In Vala example, this.say.callback is equivalent to test_gio_async_say_idle_func in C example.

Setup Gnome Development Environment in Archlinux

Many people who want to contribute to Gnome will go with Fedora, because it is the best suitable for gnome developer. But, Archlinux is as good as Fedora in terms of providing latest gnome libraries. Here I’ll explain how I setup my development environment in Archlinux using pacstrap, jhbuild and arch-chroot.

Setup Base

In your home directory, create a folder for gnome and install archlinux packages

$ mkdir -p ~/Devel/gnome/runtime
$ cd ~/Devel/gnome
$ su
# pacstrap -d runtime base base-devel
# chown -R <username>:<groupname> runtime
# exit

Here, <username>:<groupname> must be your username and groupname to make sure you are able to modify the files inside ~/Devel/gnome/runtime without any issues. The above steps will install Archlinux base packages. Now, we need to install jhbuild,


$ cd ~/Devel/gnome/checkout
$ git clone git://git.gnome.org/jhbuild
$ cd jhbuild
$ PYTHON=/usr/bin/python2 ./autogen.sh --prefix="${HOME}/Devel/gnome/runtime/usr"
$ make install

done, next step is to configure jhbuild to setup the paths properly, to do this, we need to copy the sample jhbuildrc file from jhbuild source directory to ~/.config directory and edit that file,

$ cp ~/Devel/gnome/checkout/jhbuild/examples/sample.jhbuildrc ~/.config/jhbuildrc

Here is my .jhbuildrc modifications

# -*- mode: python -*-
--- /home/mohan/Devel/gnome/checkout/jhbuild/examples/sample.jhbuildrc   2015-01-17 11:38:40.055187155 +0800
+++ /home/mohan/.config/jhbuildrc       2015-01-06 09:07:34.493161676 +0800
@@ -10,22 +10,25 @@
 # jhbuild/defaults.jhbuildrc, but can be any file in the modulesets directory
 # or a URL of a module set file on a web server.
 # moduleset = 'gnome-apps-3.12'
+moduleset = 'gnome-world'
 # A list of the modules to build.  Defaults to the GNOME core and tested apps.
 # modules = [ 'meta-gnome-core', 'meta-gnome-apps-tested' ]
 # Or to build the old GNOME 2.32:
 # moduleset = 'gnome2/gnome-2.32'
 # modules = ['meta-gnome-desktop']
+modules = ['gjs', 'farstream', 'gnome-online-accounts', 'polari', 'gnome-shell', 'glade', 'gnome-builder']
 # what directory should the source be checked out to?
-checkoutroot = '~/jhbuild/checkout'
+checkoutroot = '~/Devel/gnome/checkout'
 # the prefix to configure/install modules to (must have write access)
-prefix = '~/jhbuild/install'
+prefix = '~/Devel/gnome/runtime/usr'
 # custom CFLAGS / environment pieces for the build
 # os.environ['CFLAGS'] = '-Wall -g -O0'
+os.environ['PYTHON'] = '/usr/bin/python2'
 # extra arguments to pass to all autogen.sh scripts
 # to speed up builds of GNOME, try '--disable-static --disable-gtk-doc'

Here is the details of my changes,

  • moduleset – A moduleset is an xml file contains details (like modulename, version info, repo address, type of repo, how to build etc.,) of each and every project (we call it as module) needed for gnome environment. jhbuild maintains moduleset for each release, you can see the different modulesets inside your jhbuild directory (~/Devel/gnome/jhbuild/modulesets). “gnome-world” moduleset represent generic set which will be updated for every release. So, I use “gnome-world” to make my environment as latest as possible.
  • modules – when we execute “jhbuild build” command, jhbuild will compile only the modules listed in this place. make sure you build what you want instead of building all the gnome projects (aka “meta-gnome-desktop”)
  • checkoutroot – place where jhbuild will clone the gnome repositories. set this to ~/Devel/gnome/checkout.
  • prefix – place where jhbuild will put the compiled binaries, set this to ~/Devel/gnome/runtime/usr. If you notice, you will see that ~/Devel/gnome/runtime is the same path where we installed archlinux base, so, we basically put the gnome binaries (libraries & executables) on top of archlinux, I’ll tell you why we are doing this when I explain arch-chroot.
  • os.environ[‘PYTHON’] – set this to /usr/bin/python2 because, Archlinux’s default python is python3 but most of gnome modules don’t like python3 (especially jhbuild. see here – https://wiki.archlinux.org/index.php/JHBuild#Python_issues).


All set, its time to compile.

$ ~/Devel/gnome/runtime/usr/bin/jhbuild build

If jhbuild finds any missing libraries to compile the modules listed in jhbuildrc, it will throw error, here comes the need of arch-chroot.

Installing missing Dependencies

The reason we setup archlinux base in ~/Devel/gnome/runtime is to install any missing libraries here from arch packages using arch-chroot and packman and make sure we don’t distrub the current system. Let say, jhbuild throws that ‘spotread’ is missing when compiling colord module. ‘spotread’ executable is provided by ‘argyllcms’ package and here is the simple way to fix the dependency issue,

$ cd ~/Devel/gnome
$ su
# arch-chroot runtime /usr/bin/bash
# pacman --sync --refresh
# pacman --sync --sysupgrade
# pacman --sync argyllcms
# exit
# chown -R <username>:<groupname> runtime
# exit

Now, we can start compiling again, I suggest to switch to jhbuild environment before we compile, because jhbuild will setup necessary environment variables (like LD_LIBRARY_PATH pointing to ~/Devel/gnome/runtime/usr/lib etc.,) to make sure dependency libraries are resolved from ~/Devel/gnome/runtime/usr.

$ ~/Devel/gnome/runtime/usr/bin/jhbuild shell
$ jhbuild build
$ exit

Now, to execute the latest compiled gnome-builder,  here is the commandline

$ ~/Devel/gnome/runtime/usr/bin/jhbuild run gnome-builder

Thats it, you have your gnome development environment ready.

gistnotes – a gnome shell extension

Well, I should probably say, its basically a gnome application disguised as a shell extension. written entirely using javascript.

Nothing much to say more than what the README say here, https://github.com/mohan43u/gistnotes


This is my first contribution to gnome. you can install it through https://extensions.gnome.org/extension/917/gistnotes/. Check it out, and provide feedback.

Issue with Sabayon

Long time since I blogged. Life is crazy mate (specially after you become a husband). Personals aside, I have been waiting to blog about my experience with Sabayon.

I was a user of sabyon for about two and half years. But now, I’m a Arch user and thats one damn thing I did right to kickstart my hunger for coding again. Well, sorry sabayon developers, you guys suck!! because you dont worry about your users anymore.

Nothing wrong with the distro (I admire the stability it provided), but your attitude towards the users suck!! everytime we report a bug, you people either say raise this bug to upstream (or) raise this bug in gentoo’s bugzilla because they are the one who create the package.

If gentoo have a package and we ask it to enable it in sabayon overlay, you will say, we don’t enable some package because of one user and one can use gentoo’s overlay if they want. Dammit!! if I want to use gentoo’s overlay, why do I need to install sabayon?

Anyway, goodbye. I’m now in a true rolling distro.