GLib GError & GIO GTask

GLib GError

Odysseus uses GLib’s GError to report syntax errors for it’s templates before rendering it via a different template (which yes, means I need to error handle my error handling).

It’s a simple C struct with fields for “domain”, error code, and a textual message. Domain is the most interesting of those as it’s a “quark”, that is a string stored in a global hashmap for deduplication and cheap equality tests.

The Vala compiler wraps this with your traditional try/catch syntax, with some help from g_error_matches(), and g_error_propagate() which copies errors into the expected pointer.


That was trivial! So I’ll cover another GLib (or rather GIO) structure with Vala syntactic sugar that Odysseus benefits highly from in implementing it’s templating language.

I want to make sure loading an internal page cannot freeze your browser, so I use “async methods” to frequently hand control back to the mainloop where other events can be handled.

P.S. At “Prosody” runtime errors are silenced via it’s “Empty” type, this is generally the best I can do.

The most interesting aspect of async methods is entirely in the Vala compiler. There it compiles the async methods to:

But it’s core, async methods can call other async methods and return to wait until it’s called back by the callee at which point the opening switch statement jumps back to the current point.

The GTask for these async methods, which wraps the callback passed into the start method, contains a variaty of data including:

Or it can use these fields to control threads used to make synchronous operations async.

But to summarise to “return” a GTask:

  1. Updates it’s state
  2. Check the current mainloop context and iteration to determine whether to return immediately wait until the next “idle” event from the mainloop.
  3. Push the previous context back onto the mainloop stack.
  4. Run the callback passing itself (as type GAsyncResult) and it’s associated data, marking that as done.
  5. Notify anyone else of the completion, before restoring the mainloop stack.