Tag Archives: GLib

Automatically shutting down a daemon on inactivity

tl;dr: Use gss_service_hold() and gss_service_release() from libgsystemservice.

Automatically shutting down daemons when not in use is in vogue, and a good way of saving resources quite easily (if the service’s startup/shutdown costs are low).

libgsystemservice can do this for you automatically, if your code is based on GssService, or if you want to port over to it (which should be fairly straightforward for simple services). It supports inactivity timeouts by default; just call gss_service_hold() when you start doing some activity, and gss_service_release() when you stop.

(Also, look, it’s neat that you can generate documentation and automatically publish it from your master branch using GitLab CI!)

libgsystemservice: a library for writing D-Bus system services

Having written a few D-Bus system services recently, it felt like I was cargo-culting the same bits of code in all of them. I’ve split some of that out into a new library, libgsystemservice, which I hope will grow to contain all the bits people need to write D-Bus system services and other system daemons.

At the moment, it includes a way to load configuration files from multiple directories (with /etc taking priority over /usr/share, for example); tracking of D-Bus peers which have interacted with your service, and their credentials; and an equivalent of GApplication for system services. (GApplication only works on the session bus, and has various features targetting user applications which aren’t appropriate for system services.)

We’re using this code within Endless at the moment; but the more users it has, the better. Feedback and contributions are very welcome on GNOME’s GitLab.

GTK+ hackfest and FOSDEM: outcomes

Last Thursday and Friday was the GTK+ hackfest in Brussels. Matthias and Timm have blogged about GTK+ discussions already. This post is about the GLib side of things.

Firstly, we’re moving to Meson, but with no regressions from autotools. The plan is to target functional compatibility with autotools for 2.58, to keep both build systems in parallel for a release or two, and then drop autotools as soon as we can be satisfied there are no regressions for any of our features or supported platforms. I’d like to encourage distributions and developers to start trying to build GLib with Meson, seeing what breaks, and filing bugs.

Secondly, we’re migrating to gitlab, slowly. The first step is to migrate from cgit to gitlab, which will allow us to set up continuous integration for GLib. This will be a big win. The second step will be to migrate Bugzilla to gitlab. That’s going to take a bit longer, since there are issues with getting the data out of Bugzilla efficiently. All open bugs will be transferred, just like with the other gitlab transitions so far.

The maintainership status of GLib was also discussed. We are short on people power, and would appreciate assistance. If your project or company relies on GLib, please consider helping out with patch review or writing patches. We have three part-time maintainers who can provide guidance and help. We’re particularly interested in finding people to help maintain the platform ports of GLib, like Windows, OS X or BSD, more officially. Find us in #gtk+ on irc.gnome.org.

We also discussed a number of other, smaller features and issues, which might get handled for 2.58 depending on time. If you would like to work on any of them, please do! We can provide guidance and patch review in Bugzilla.

Thanks to Matthias and Emmanuele for organising the hackfest, Allison for turning up and imparting sage GLib wisdom, and Purism for kindly sponsoring dinner on Friday night.

GTK+ hackfest and FOSDEM

Courtesy of my employer, Endless (we’re  hiring), I’m at the GTK+ hackfest in Brussels, which is acting as my warm up for FOSDEM 2018. I’m representing the assorted GLib maintainers, aiming to look at the roadmap for GLib 2.58, and what we need to do to finish off GLib 2.56. If you’ve got suggestions for new features or changes to GLib, get in touch or file a bug!

Debugging critical warnings from GLib code

tl;dr: G_DEBUG=fatal-warnings gdb ./my-program

If you have some code which uses GLib, and it emits a critical warning, for example if a g_return_if_fail() check fails or if a g_warning() message is emitted, how do you track it down and debug it?

Run your code under gdb with G_DEBUG=fatal-warnings (for g_return_if_fail() and g_warning()) or G_DEBUG=fatal-criticals (for g_return_if_fail()), and gdb will break execution when the failing precondition or warning is reached. If there are multiple warnings and you want to skip through to get to a particular one, just use the continue command in gdb until you reach the one you want.

Where are messages on the terminal coming from?

From a discussion on #gtk+ this morning: if you’re using recent versions of GLib with structured logging support, and you want to work out which bit of your code is causing a certain message to be printed to the terminal, run your application in gdb and add a breakpoint on g_log_writer_standard_streams.

(This assumes you’re using the default log writer function; if not, you need to add a breakpoint on something in your writer function.)

Instrumenting the GLib main loop with Dunfell

tl;dr: Visualise your main context and sources using Dunfell. Feedback and ideas welcome.

At the DX hackfest, I’ve been working on a new tool for instrumenting and visualising the behaviour of the GLib main context (or main contexts) in your program.

Screenshot from 2016-01-29 11-17-35

It’s called Dunfell (because I’m a sucker for hills) and at a high level it works by using SystemTap to record various GMainContext interactions in your program, saving them to a log file. The log file can then be examined using a viewer program.

The source is available on GitLab or GitHub because I still haven’t decided which is better.

In the screenshot above, each vertical line is a thread, each blue box is one dispatch phase of the main context which is currently running on that thread, each orange blob is a new GSource being created, and the green blob is a GSource which has been selected for closer inspection.

At the moment, it requires a couple of GLib patches to add some more SystemTap probe points, and it also requires a recent version of GTK+. It needs SystemTap, and I’ve only tested it on Fedora, so it might need some patching to work with the SystemTap installed on other distributions.

Screenshot from 2016-01-29 11-57-39

This screenshot is of a trace of the buffered-input-stream test from GIO, showing I/O callbacks being made across threads as idle source callbacks.

More visualisation ideas are welcome! At the moment, what Dunfell draws is quite simplistic. I hope it will be able to solve various common debugging problems eventually but suggestions for ways to do this intuitively, or for other problems to visualise, are welcome. Here are the use cases I was initially thinking about (from the README):

  • Detect GSources which are never added to a GMainContext.
  • Detect GSources which are dispatched too often (i.e. every main context iteration).
  • Detect GSources whose dispatch function takes too long (and hence blocks the main context).
  • Detect GSources which are never removed from their GMainContext after being dispatched (but which are never dispatched again).
  • Detect GMainContexts which have GSources attached or (especially) events pending, but which aren’t being iterated.
  • Monitor the load on each GMainContext, such as how many GSources it has attached, and how many events are processed each iteration.
  • Monitor ongoing asynchronous calls and GTasks, giving insight into their nesting and dependencies.
  • Monitor unfinished or stalled asynchronous calls.
  • Allow users to record logs to send to the developers for debugging on a different machine. The users may have to install additional software to record these logs (some component of Dunfell, plus its dependencies), but should not have to recompile or otherwise modify the program being debugged.
  • Work with programs which purely use GLib, through to programs which use GLib, GIO and GTK+.
  • Allow visualisation of this data, both in a standalone program, and in an IDE such as GNOME Builder.
  • Allow visualising differences between two traces.
  • Minimise runtime overhead of logging a program, to reduce the risk of disturbing race conditions by enabling logging.
  • Connecting to an already-running program is not a requirement, since by the time you’ve decided there’s a problem with a program, it’s already in the wrong state.

G_OBJECT and G_IS_OBJECT allow NULL

tl;dr: G_OBJECT(NULL) evaluates to NULL with no side effects; G_IS_OBJECT(NULL) evaluates to FALSE with no side effects. The same is true for these macros for GObject subclasses.

Someone recently pointed out a commonly-misunderstood point about the GObject casting and type checking macros: they all happily accept NULL, without printing errors or causing assertion failures.

If you call G_OBJECT (NULL), it is a dynamically checked type cast of NULL, and evaluates to NULL, just as if you’d written (GObject *) NULL.

If you call G_IS_OBJECT (NULL), it evaluates to FALSE.

The misconception seems to be that they cause assertion failures. I think that arises from the fact that G_IS_OBJECT is commonly used with g_return_if_fail(), which does cause an assertion failure if G_IS_OBJECT returns FALSE.

Similarly, this all applies to the macros for GObject subclasses, like GTK_WIDGET and GTK_IS_WIDGET, or G_FILE and G_IS_FILE, etc.

Reference: g_type_check_instance_cast() and g_type_check_instance_is_a(), which are what these macros evaluate to.

GLib now has a datagram interface

For those who like their I/O packetised, GLib now has a companion for its GIOStream class — the GDatagramBased interface, which we’ve implemented as part of R&D work at Collabora. This is designed to be implemented by any class which does datagram-based I/O. GSocket implements it, essentially as an interface to recvmmsg() and sendmmsg(). The upcoming DTLS support in glib-networking will use it.

How is it shaped? Basically as a GLib-shaped version of recvmmsg() and sendmmsg(), where GInputMessage and GOutputMessage are effectively equivalent to struct mmsghdr, and GInputVector and GOutputVector are equivalent to struct msghdr.

The interface is designed around polling, potentially-blocking I/O. What’s ‘potentially-blocking’ about it? The timeout parameter. Set it to zero for non-blocking behaviour, where the functions will return G_IO_ERROR_WOULD_BLOCK if they would block. Set it negative for blocking behaviour, where the functions will not return until they can do at least some I/O. Set it positive for timeout behaviour, where the functions will block for the given number of microseconds, then return G_IO_ERROR_TIMED_OUT if they managed to perform no I/O.

gint
g_datagram_based_receive_messages (GDatagramBased   *datagram_based,
                                   GInputMessage    *messages,
                                   guint             num_messages,
                                   gint              flags,
                                   gint64            timeout,
                                   GCancellable     *cancellable,
                                   GError          **error);

gint
g_datagram_based_send_messages    (GDatagramBased   *datagram_based,
                                   GOutputMessage   *messages,
                                   guint             num_messages,
                                   gint              flags,
                                   gint64            timeout,
                                   GCancellable     *cancellable,
                                   GError          **error);

GSource *
g_datagram_based_create_source    (GDatagramBased   *datagram_based,
                                   GIOCondition      condition,
                                   GCancellable     *cancellable);
GIOCondition
g_datagram_based_condition_check  (GDatagramBased   *datagram_based,
                                   GIOCondition      condition);
gboolean
g_datagram_based_condition_wait   (GDatagramBased   *datagram_based,
                                   GIOCondition      condition,
                                   gint64            timeout,
                                   GCancellable     *cancellable,
                                   GError          **error);

Currently, the API (particularly GInputMessage and GOutputMessage, due to the way they are used as in-out parameters) doesn’t support introspection. This can be added in future if needed by creating some convenience API for allocating and freeing the message structures as boxed types.

The grand, overarching plan is for this to appear in a libnice version near you, some time soon, exposing the whole of an ICE connection as a GDatagramBased.

If you think the name is bad, tough. It has been bikeshedded enough already.