<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<?xml-stylesheet href="http://research.operationaldynamics.com/blogs/atom.css" type="text/css"?>

<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">

<title type="text/plain">Andrew Cowie</title>
<tagline type="text/plain">Observations about the life and times of the GNOME open source Desktop project</tagline>
<link rel="alternate" type="text/html" href="http://research.operationaldynamics.com/blogs" />
<id>tag:research.operationaldynamics.com,2008:/andrew/software/gnome-desktop</id>
<generator url="http://www.blosxom.com/" version="2.0">Blosxom</generator>
<modified>2008-10-05T13:05:00Z</modified>

<entry>
<id>tag:research.operationaldynamics.com,2008:/andrew/software/gnome-desktop/gtk-bug-56070</id>
<link rel="alternate" type="text/html" href="http://research.operationaldynamics.com/blogs/andrew/software/gnome-desktop/gtk-bug-56070.html" />
<title type="text/plain">Swat!</title>
<dc:subject>/andrew/software/gnome-desktop</dc:subject>
<issued>2008-08-01T05:38:00Z</issued>
<modified>2008-08-01T05:38:00Z</modified>
<author>
  <name>Andrew Cowie</name>
</author>
<content type="application/xhtml+xml" xml:base="http://research.operationaldynamics.com/blogs" xml:lang="en" xml:space="preserve" mode="xml">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Huge kudos are due to <a href="http://blogs.gnome.org/bratsche/">Cody Russell</a> for having fixed one of the <a href="http://bugzilla.gnome.org/show_bug.cgi?id=56070">longest-standing</a> bugs in GTK. 11 June 2001!</p>

<p>Cody only got involved in this issue recently, but he took the time to really dig into it, examine different hypothesises, and test like crazy. This was remarkable: it&#8217;s not every day you see someone wade into a bug that&#8217;s been open for over half a decade and with over a hundred comments, and then persist for over a year to get it solved.</p>

<p>Way to go!</p>

<p>AfC</p>
</div>
</content>
</entry>

<entry>
<id>tag:research.operationaldynamics.com,2007:/andrew/software/gnome-desktop/gtk-for-gnome-2.20</id>
<link rel="alternate" type="text/html" href="http://research.operationaldynamics.com/blogs/andrew/software/gnome-desktop/gtk-for-gnome-2.20.html" />
<title type="text/plain">New GTK in GNOME 2.20</title>
<dc:subject>/andrew/software/gnome-desktop</dc:subject>
<issued>2007-06-07T13:46:00Z</issued>
<modified>2007-06-07T13:46:00Z</modified>
<author>
  <name>Andrew Cowie</name>
</author>
<content type="application/xhtml+xml" xml:base="http://research.operationaldynamics.com/blogs" xml:lang="en" xml:space="preserve" mode="xml">
<div xmlns="http://www.w3.org/1999/xhtml"><p>I&#8217;m glad to hear that the release-team has decided to <a href="http://mail.gnome.org/archives/devel-announce-list/2007-June/msg00001.html">push ahead</a> and approve  Glib 2.14 and GTK+ 2.12 for the next GNOME release. Awesome!</p>

<p><em>One of the diseases that arises in group psychology is that sometimes it is hard to say &#8220;yes&#8221;. It looked for a while like people on one side or the other (or both) were going to flinch. I&#8217;m glad that didn&#8217;t happen. I know there was some proactive negotiation and give-and-take on the part of both the GTK hackers and of the release-team. Well done everyone.</em></p>

<p>AfC</p>
</div>
</content>
</entry>

<entry>
<id>tag:research.operationaldynamics.com,2007:/andrew/software/gnome-desktop/gtk-thread-awareness</id>
<link rel="alternate" type="text/html" href="http://research.operationaldynamics.com/blogs/andrew/software/gnome-desktop/gtk-thread-awareness.html" />
<title type="text/plain">Multi-threaded GTK applications - Part 1: Misconceptions</title>
<dc:subject>/andrew/software/gnome-desktop</dc:subject>
<issued>2007-05-23T09:50:00Z</issued>
<modified>2007-05-23T09:50:00Z</modified>
<author>
  <name>Andrew Cowie</name>
</author>
<content type="application/xhtml+xml" xml:base="http://research.operationaldynamics.com/blogs" xml:lang="en" xml:space="preserve" mode="xml">
<div xmlns="http://www.w3.org/1999/xhtml"><p>I think my favourite message of the last year has to be something Tristan <a href="http://mail.gnome.org/archives/gtk-list/2007-January/msg00157.html">wrote</a>:</p>

<blockquote>
  <p>&#8220;it is really plain and simple thread programming, you just have to really know what you&#8217;re doing.&#8221;</p>
</blockquote>

<p>One of the most frequently asked questions in the GTK mailing lists is &#8220;How do I use threads with GTK&#8221;. Actually, the question is more often &#8220;I&#8217;ve started writing a GTK program, and it doesn&#8217;t work. What the hell?&#8221; and it quickly emerges that they&#8217;re trying to do a multi-threaded GTK app, and doing it wrong.</p>

<p>The conventional answer has long been that &#8220;<strong>you must only make GTK library calls from the main thread</strong>&#8221; (that is, the thread that executed <code>gtk_main()</code> and is therefore the one running the GTK main loop). What usually follows is advice to create a producer-consumer relationship to dispatch requests from the worker threads to the main [loop] thread and have the code to actually do the UI updates in separate code there. Frankly, this is rather cumbersome when all you want to do is a quick worker thread so you don&#8217;t freeze the UI by blocking the main loop, and then a couple of quick (but very case specific) UI updates to report the result. Non-trivial validation and then a database commit upon pressing &#8220;OK&#8221; is a classic example.</p>

<p>So, I&#8217;ve been studying this carefully for the last several months. Searching the GNOME archives turns up any number of <a href="http://www.google.com/search?q=(GDK+OR+GTK)+threads+site:mail.gnome.org">fascinating threads</a> on the topic. (ooof, bad pun, sorry) and there is frequent reference across GTK documentation and tutorials about the necessity to guard all GTK calls. </p>

<p>And yet: despite all the traffic and opinion that you must only make GTK calls from the main thread, <strong>this is not actually correct</strong>. At least I don&#8217;t think it is. Perhaps you can tell me if my conclusions are correct.</p>

<p>As you dig further, you start to realize that the requirement is <em>not</em> that you make calls from the main thread only, but <strong>that all GTK calls must be made within the main <em>lock</em></strong> (the GDK lock actually). This is stated quite clearly on the <a href="http://developer.gnome.org/doc/API/2.0/gdk/gdk-Threads.html#id2755107">canonical GDK Threads page</a> which cites:</p>

<blockquote>
  <p>GTK+ is &#8220;thread aware&#8221; but not thread safe &#8212; it provides a global lock controlled by <code>gdk_threads_enter()</code> and <code>gdk_threads_leave()</code> which protects all use of GTK+. That is, only one thread can use GTK+ at any given time.</p>
</blockquote>

<p>You&#8217;ll note that it doesn&#8217;t say anything about the &#8220;main loop thread&#8221;. And this is where the confusion sets in.</p>

<h2>Convenience APIs shield you from the truth</h2>

<p>People get the message that they have to put <code>gdk_threads_enter()</code>/<code>leave()</code> around their GTK calls from other threads pretty quickly. But two things tend to be overlooked:</p>

<p>It turns out that you&#8217;re supposed to put <code>gdk_threads_enter()</code>/<code>leave()</code> around the call you make to <code>gtk_main()</code>. I suppose that this is implicit in the injunction to protect all GTK calls, but I know I&#8217;m not the only one to have had the impression that the main loop was special somehow. It certainly isn&#8217;t explicit on the GDK threads API page, and although it turns up (sort of) in the code examples there, the number of people that get this wrong is staggering. So I think we&#8217;ll need to improve that documentation a bit. <em>(I&#8217;ll submit a patch depending on the feedback I get after this series of posts)</em></p>

<p>So now with the lightest of refactoring, C side we have this:</p>

<pre><code>int main(int argc, char** argv) {
    g_threads_init()
    gdk_threads_init()
    gtk_init()
    ...
    gdk_threads_enter()
    gtk_main()
    gdk_threads_leave()
}
</code></pre>

<p>The second problem is more subtle. Because signal callbacks happen from within  the main loop (blocking it), and since the thread running the main loop has traditionally been though of as &#8220;special&#8221;, people quickly forget that they need to protect the GTK calls in their callbacks, especially if the bulk of their GTK programming has been single threaded C code. This is <em>dramatically</em> exacerbated by the fact that if you properly did <code>gtk_threads_enter()</code> before calling <code>gtk_main()</code>, then when you get a callback you are already in the GDK lock and you don&#8217;t even have to think about it. So people don&#8217;t.</p>

<p>This is a massive convenience, of course. GTK programming in C is already ridiculously verbose, and if people had to manually surround every individual GTK call with the <code>enter()</code>/<code>leave()</code> functions like this:</p>

<pre><code>void clicked_cb(GtkButton* button, gpointer data) {
    gdk_threads_enter();
    gtk_widget_set_sensitive(button, TRUE);
    gdk_threads_leave();

    gdk_threads_enter();
    gtk_button_set_label(GTK_BUTTON(button), "Blah");
    gdk_threads_leave();
    ...
}
</code></pre>

<p>they&#8217;d go slightly crazy. Even having to do it at the beginning and end of a callback function:</p>

<pre><code>void clicked_cb(GtkButton* button, gpointer data) {
    gdk_threads_enter();
    gtk_widget_set_sensitive(button, TRUE);
    gtk_button_set_label(GTK_BUTTON(button), "Blah");
    ...
    gdk_threads_leave();
}
</code></pre>

<p>would still be <em>way</em> too cumbersome. But because GTK callbacks are within the main loop and from the main thread, no one ever has to think much about it, because we all just do this:</p>

<pre><code>void clicked_cb(GtkButton* button, gpointer data) {
    gtk_widget_set_sensitive(button, TRUE);
    gtk_button_set_label(GTK_BUTTON(button), "Blah");
    ...
}
</code></pre>

<p>In fact, the first two examples were <strong>wrong</strong> because the default implementation of the GDK lock functions is a mutex that is not reentrant, and that would have deadlocked! So not only do we not have to think about the thread safety issue, C side we can&#8217;t think about it. Bad.</p>

<h2>But wait a minute. If the main loop is in the lock, how can any other thread run?</h2>

<p>This is the question that finally got me on the right track. How <em>can</em> any other thread ever execute a GTK call?</p>

<p>It took me overriding the GDK lock grab and release functions with <a href="http://developer.gnome.org/doc/API/2.0/gdk/gdk-Threads.html#gdk-threads-set-lock-functions"><code>gdk_threads_set_lock_functions()</code></a> and sticking in some <code>g_debug()</code>s to find this out, but there&#8217;s a little detail that no one tells you: <strong>the GTK main loop releases its lock as it cycles</strong>, and it turns out that GTK itself <em>is</em> properly written to call the <code>enter()</code> and <code>release()</code> functions (via the macros <code>GDK_THREADS_ENTER()</code> and <code>GDK_THREADS_LEAVE()</code>).</p>

<p>So GTK is indeed thread-aware, if not quite thread-safe without a little help from the programmer.</p>

<p>Thus you <em>don&#8217;t</em> need to go through the nightmare of setting up a dispatcher mechanism just to make changes to the UI. From any other thread, you just surround your GTK calls with the grab and release functions, and you&#8217;re on your way.</p>

<p>In hindsight, all this information was out there; I just came across <a href="http://mail.gnome.org/archives/gtk-devel-list/2007-January/msg00137.html">this</a> which, now that I understand it, clearly says what the main loop is up to. Still, though, there&#8217;s a lot of context. As Tristan said, you have to know what you&#8217;re doing.</p>

<h2>Implications</h2>

<p>There&#8217;s a shining possibility lurking within all this: what happens if you replace the simplistic GDK lock with a reentrant (aka recursive) one? You&#8217;re not going to believe this, but it works, and it works well. And the implication for a language binding like java-gnome is extraordinary: by combining a reentrant monitor with something that automatically locks all the GTK calls, it looks like <strong>our Java bindings might be able to be thread safe</strong>! That would really be something.</p>

<p>I&#8217;ll show you what I&#8217;ve found <a href="http://research.operationaldynamics.com/blogs/andrew/software/java-gnome/thread-safety-for-java.html">tomorrow</a>.</p>

<p>AfC</p>
</div>
</content>
</entry>

<entry>
<id>tag:research.operationaldynamics.com,2007:/andrew/software/gnome-desktop/fascinating-gtk-canvas</id>
<link rel="alternate" type="text/html" href="http://research.operationaldynamics.com/blogs/andrew/software/gnome-desktop/fascinating-gtk-canvas.html" />
<title type="text/plain">Fascinating thread: GtkCanvas requirements</title>
<dc:subject>/andrew/software/gnome-desktop</dc:subject>
<issued>2007-04-30T10:47:00Z</issued>
<modified>2007-04-30T10:47:00Z</modified>
<author>
  <name>Andrew Cowie</name>
</author>
<content type="application/xhtml+xml" xml:base="http://research.operationaldynamics.com/blogs" xml:lang="en" xml:space="preserve" mode="xml">
<div xmlns="http://www.w3.org/1999/xhtml"><p>A discussion has been taking place on <a href="http://mail.gnome.org/mailman/listinfo/gtk-devel-list"><code>gtk-devel-list</code></a> this month as a number of GNOME hackers discuss <a href="http://mail.gnome.org/archives/gtk-devel-list/2007-April/msg00076.html">the requirements that a future <code>GtkCanvas</code> widget might have</a>.</p>

<p>A canvas widget is all about drawing; while many requirements for customized user interface <em>don&#8217;t</em> need such a thing (because you can always pack together various other widgets into a new composite widget that achieves the effect you&#8217;re aiming for), in the more general case you need to start drawing lines and shapes &#8212; and this is where people usually run into trouble. For one thing, drawing of any kind is generally fairly complicated, but most of the pain comes as a result of drawing things at bitmap (pixel by pixel) level &#8212; later on, anything that needs to scale (zoom in, zoom out) the resultant pixmaps is bound to look terrible.</p>

<p>That, of course, is what vector graphics are all about, and so the obvious thing is to use such mechanisms to do the low level drawing. For a while now, we&#8217;ve had an outstanding vector drawing library in freedesktop land, and that&#8217;s <a href="http://www.cairographics.org/">Cairo</a>. And while Cairo is already used for quite a number of things in GTK, and while there are various higher level Canvas widgets floating around, the most interesting part of the whole thread to me was when it was pointed out that if a new <code>GtkCanvas</code> (in the form of a slightly lower level artifact) was used to render <strong>all</strong> the [standard] Widgets provided by GTK, then suddenly the zooming, resizing, and other warping that accessibility tools need would all be <em>fait accompli</em> in the toolkit itself. And it&#8217;s not just accessibility: someone pointed out that if we made it this far, then at last we&#8217;d have high resolution screen shots to paper which would make printed documentation look stunning.</p>

<p>Fascinating thread.</p>

<p>AfC</p>
</div>
</content>
</entry>

<entry>
<id>tag:research.operationaldynamics.com,2005:/andrew/software/gnome-desktop/hover-audio</id>
<link rel="alternate" type="text/html" href="http://research.operationaldynamics.com/blogs/andrew/software/gnome-desktop/hover-audio.html" />
<title type="text/plain">Audio snippets when hovering</title>
<dc:subject>/andrew/software/gnome-desktop</dc:subject>
<issued>2005-07-22T01:12:00Z</issued>
<modified>2005-07-22T01:12:00Z</modified>
<author>
  <name>Andrew Cowie</name>
</author>
<content type="application/xhtml+xml" xml:base="http://research.operationaldynamics.com/blogs" xml:lang="en" xml:space="preserve" mode="xml">
<div xmlns="http://www.w3.org/1999/xhtml"><p>I was waving my mouse over my desktop where I&#8217;d downloaded a few recent
episodes of <a href="http://www.lugradio.org/">LugRadio</a> and suddenly when a few seconds of babble with a
British accent bubbled out of my speakers. </p>

<p>Stunned silence.</p>

<p>I didn&#8217;t think I&#8217;d clicked on the file to actually open it, but ok, fine. Wait
for <code>totem</code> to fire up to play the <code>.ogg</code>. Waiting, waiting. Hm. <code>totem</code>
<em>didn&#8217;t</em> fire up. I <em>hadn&#8217;t</em> double clicked on it. Huh?</p>

<p>So I waved my mouse back over one of the <code>.ogg</code>s, and then another sound bite
(the first few seconds of the episode) came out of my speakers. </p>

<p>Whoa!</p>

<p>So just as the GNOME desktop (ok, <code>nautilus</code> presumably) does a thumbnail of an
image (ok, no biggie) or from a video clip (hey, neat), it does an audible
thumbnail to help you know identify what a given audio file is.</p>

<p>Cool!</p>

<p>AfC</p>
</div>
</content>
</entry>


</feed>
