Planet Igalia

May 16, 2012

Xabier Rodríguez Calvar

Aura made me Qt Ambassador

As I already said the other day in Twitter, I became Qt Ambassador because of Aura. The only problem is that is a project-person program, meaning that it is granted to a person because of having worked on a project. Aura was a project developed by three Igalians, who were Miguel, Víctor and me and I consider a bit unfair that it was granted only to me because they deserve it as much as I do.

The procedure I followed was:

  • Applying with Aura
  • When that was accepted, I submitted Aura project page.
  • After the publication I was told that I was going to receive the Qt Ambassador Merchansise

Does anybody know if more people can become ambassadors for the same project and how?

by calvaris at May 16, 2012 03:32 PM

Andy Wingo

stranger in these parts

My JSConf 2012 video is out! Check it out:

Visit blip.tv to watch in your browser

The talk is called "Stranger in these parts: A hired gun in the JS corral", and in it I talk about my experiences as a Schemer in the implementation world, with a focus on JavaScriptCore, the JS implementation of the WebKit project.

If you want, you can fetch the slides or the notes. If you were unable to play the video in the browser, you can download it directly (25 minutes, ~80 MB, CC-BY-SA).

Special thanks to the A/V team for the fine recording. My talk was the first one that used the wireless mics, and it turned out there was some intermittent interference. They corrected this in later talks by double-miking the speakers. In my case, it was fortunate that they recorded the room as well, and with (I would imagine) a fair amount of post-processing the sound is perfectly intelligible. Cheers!

Finally, there were a number of other interesting talks whose recordings are starting to come out. I especially liked David Nolen's funhouse of ClojureScript and logic programming. It was pleasantly strange to see him mention Peter Norvig's 1992 book, Paradigms of Artificial Intelligence Programming, because I did too, and I think someone else did as well. Three people mentioning a somewhat obscure 20-year-old book, what are the odds?

I also liked Vyacheslav's amusing talk on V8's optimizing compiler. He actually showed some assembler! Folks that read this webrag might find it interesting. Dan Ingalls' talk was fun too. The ending scene was pretty surreal; be sure to watch all the way through.

Thanks again to the JSConf organizers for the invitation to speak. It was a pleasure to get to hang around the lively and energetic JS community. Happy hacking, all!

by Andy Wingo at May 16, 2012 11:35 AM

May 14, 2012

Andy Wingo

doing it wrong: cse in guile

Greetings, readers! It's been a little while, but not because I haven't been doing anything, or nothing worth writing about. No, the reason I haven't written recently is because the perceived range of my ignorance has been growing faster than the domain of my expertise.

Knowledge may well be something one can dominate, but ignorance must forever be a range, stretching off to a hazy horizon. Climbing the hill of JavaScript implementations has let me see farther out on that plain. I think it's only the existence of the unknown unknowns that can let one muster up the arrogance to write at all.

But back to domains and dominators later. To begin, I note that there is very little in the way of correct, current, and universal folk wisdom as to how to implement a programming language. Compiler hackers are priests of their languages, yes, but their temples are in reality more or less isolated cults, in which the values of one's Gods may be unknown or abhorrent to those of others. Witness the attention paid to loop optimizations in some languages, compared to garbage collection in others, or closures in still others.

In my ecumenical capacity as abbot of Guile and adjunct deacon of JavaScriptCore, sometimes I'm tempted to mix rites: to sprinkle the holy water of lexical scope optimizations on JS, and, apropos of this article, to exorcise common subexpressions in Scheme.

As one might well imagine, the rites of one cult must be adapted to circumstances. I implemented CSE for Guile, but I don't know if it was actually a win. In this article I'll go into what CSE is, how it works in Guile, why it probably won't survive in its present form.

cse: common subexpression elimination

I implemented a source-to-source optimization pass in Guile that eliminates common subexpressions. It actually does both more and less than that: it propagates predicates and eliminates effect-free statements as well, and these latter optimizations are why I implemented the pass in the first place.

Let me give an example. Let's imagine we implement a binary tree in Guile, using the records facility.

(use-modules (srfi srfi-9))

(define-record-type btree
  (make-btree elt left right)
  btree?
  (elt btree-elt)
  (left btree-left)
  (right btree-right))

(define *btree-null* #f)

(define (btree-cons head tail)
  (if (btree? tail)
      (let ((elt (btree-elt tail)))
        (if (< elt head)
            (make-btree elt
                        (btree-left tail)
                        (btree-cons head (btree-right tail)))
            (make-btree elt
                        (btree-cons head (btree-left tail))
                        (btree-right tail))))
      (make-btree head
                  *btree-null*
                  *btree-null*)))

That's enough to illustrate my point, I think. We have the data type, the base case, and a constructor. Of course in Haskell or something with better data types it would be much cleaner, but hey, let's roll with this.

If you look at btree-cons, it doesn't seem to be amenable in its current form to classic common subexpression elimination. People don't tend to write duplicated code. You see that I bound the temporary elt instead of typing (btree-elt btree) each time, and that was partly because of typing, and partly out of some inner efficiency puritan, telling me I shouldn't write duplicate expressions. (Cult behavior, again!)

But, note that all of these record abstractions will probably inline, instead of calling out to procedures. (They are implemented as inlinable procedures. Yes, it would be better to have cross-module inlining, but we don't, so this is what we do.) In general, syntactic abstraction in Scheme can lead to duplicate code. Apologies in advance for this eyeball-rending torrent, but here's a listing of what btree-cons reduces to, after expansion and partial evaluation:

(define (btree-cons head tail)
  (if (and (struct? tail)
           (eq? (struct-vtable tail) btree))
      (let ((elt (if (eq? (struct-vtable tail) btree)
                     (struct-ref tail 0)
                     (throw 'wrong-type-arg
                            'btree-elt
                            "Wrong type argument: ~S"
                            (list tail)
                            (list tail)))))
        (if (< elt head)
            (let ((left (if (eq? (struct-vtable tail) btree)
                            (struct-ref tail 1)
                            (throw 'wrong-type-arg
                                   'btree-left
                                   "Wrong type argument: ~S"
                                   (list tail)
                                   (list tail))))
                  (right (btree-cons
                           head
                           (if (eq? (struct-vtable tail) btree)
                               (struct-ref tail 2)
                               (throw 'wrong-type-arg
                                      'btree-right
                                      "Wrong type argument: ~S"
                                      (list tail)
                                      (list tail))))))
              (make-struct/no-tail btree elt left right))
            (let ((left (btree-cons
                          head
                          (if (eq? (struct-vtable tail) btree)
                              (struct-ref tail 1)
                              (throw 'wrong-type-arg
                                     'btree-left
                                     "Wrong type argument: ~S"
                                     (list tail)
                                     (list tail)))))
                  (right (if (eq? (struct-vtable tail) btree)
                             (struct-ref tail 2)
                             (throw 'wrong-type-arg
                                    'btree-right
                                    "Wrong type argument: ~S"
                                    (list tail)
                                    (list tail)))))
              (make-struct/no-tail btree elt left right))))
      (let ((left *btree-null*) (right *btree-null*))
        (make-struct/no-tail btree head left right))))

Again, I'm really sorry about that, and it's not just for your eyes: it's also because that's a crapload of code for what should be a simple operation. It's also redundant! There are 6 checks that btree is in fact a btree, when only one is needed semantically. (Note that the null case is not a btree, of course.)

Furthermore, all of the checks in the first arm of the if are redundant. The code above is what the optimizer produces -- which is, you know, turrible.

So, I thought, we could run a pass over the source that tries to propagate predicates, and then tries to fold predicates whose boolean value we already know.

And that's what I did. Here's what Guile's optimizer does with the function, including the CSE pass:

(define (btree-cons head tail)
  (if (and (struct? tail)
           (eq? (struct-vtable tail) btree))
      (let ((elt (struct-ref tail 0)))
        (if (< elt head)
            (let ((left (struct-ref tail 1))
                  (right (btree-cons head (struct-ref tail 2))))
              (make-struct/no-tail btree elt left right))
            (let ((left (btree-cons head (struct-ref tail 1)))
                  (right (struct-ref tail 2)))
              (make-struct/no-tail btree elt left right))))
      (let ((left *btree-null*) (right *btree-null*))
        (make-struct/no-tail btree head left right))))

This is much better. It's quite close to the source program, except the symbolic references like btree-elt have been replaced with indexed references. The type check in the predicate of the if expression propagated to all the other type checks, causing those nested if expressions to fold.

Of course, CSE can also propagate bound lexicals:

(let ((y (car x)))
  (car x))
=> (let ((y (car x)))
     y)

This is the classic definition of CSE.

but is it a win?

I should be quite pleased with the results, except that CSE makes Guile's compiler approximately twice as slow. Granted, in the long run, this should be acceptable: code is usually run many more times than it is compiled. But this is a fairly expensive pass, and yet at the same time it's not as good as it could be.

In order to get to the heart of the matter, I need to explain a little about the implementation. CSE is a post-pass, that runs after partial evaluation (peval). I tried to make it a part of peval, as the two optimizations are synergistic -- oh yes, let's revel in that word -- are you feeling it? -- but it was too complicated in the end. The reason is that in functions like this:

(define (explode btree)
  (unless (btree? btree)
    (error "not a btree" btree))
  (values (btree-head btree)
          (btree-left btree)
          (btree-right btree)))

Here we have a sequence of two expressions. Since the first one bails out if the predicate is false, we should propagate a true predicate past the first expression. This means that running CSE on an expression returns two values: the rewritten expression, given the predicates already seen; and a new set of predicates that the expression asserts. We should be able to use these new assertions to elide the type checks in the second expression. And indeed, Guile can do this.

Perhaps you can see the size of the problem now. CSE is a pass that runs over all code, building up an ordered set of expressions that were evaluated, and in what context. When it sees a new expression in a test context -- as the predicate in an if -- it checks to see if the set contains that expression (or its negation) already, in test context, and if so tries to fold the expression to true or false. Already doing this set lookup and traversal is expensive -- at least N log N in the total size of the program, with some quadratic components in the case an expression is found, and also with high constant factors due to the need for custom hash and equality predicates.

The quadratic factor comes in when walking the set to see if the elimination is valid. Consider:

(if (car x)
    (if (car x) 10 20)
    30)

Here, we should be able to eliminate the second (car x), folding to (if (car x) 10 30). However, in this one:

(if (car x)
    (begin
      (y)
      (if (car x) 10 20))
    30)

If we don't know what (y) does, then we can't fold the second test, because perhaps (y) will change the contents of the pair, x. The information that allows us to make these decisions is effects analysis. For the purposes of Guile's optimizer, (car x) has two dependencies and can cause two effects: it depends on the contents of a mutable value, and on the value of a toplevel (x), and can cause the effect of an unbound variable error when resolving the toplevel, or a type error when accessing its car. Two expressions commute if neither depends on effects that the other causes.

I stole the idea of doing a coarse effects analysis, and representing it as bits in a small integer, from V8. Guile's version is here: effects.scm. The ordered set is a form of global value numbering. See the CSE pass here: cse.scm.

The commute test is fairly cheap, but the set traversal is currently a bit expensive.

and for what?

As I have indicated, the pass does do something useful on real programs, as in the binary tree example. But it does not do all it could, and it's difficult to fix that, for a few reasons.

Unlike traditional CSE, Guile's version of it is interprocedural. Instead of operating on just one basic block or one function, it operates across nested functions as well. However, only some dependencies can commute across a function boundary. For example:

(lambda (x)
  (if (pair? x)
      (let ((y (car x)))
        (lambda ()
          (and (pair? x) (car x))))))

Can the first pair? test propagate to the second expression? It can, because pair? does not depend on the values of mutable data, or indeed on any effect. If it's true once, it will always be true.

But can we replace the second (car x) with y? No, because (car x) has a dependency on mutable data, and because we don't do escape analysis on the closure, we don't let those dependencies commute across a procedure boundary. (In this case, even if we did escape analysis, we'd have the same conclusion.)

However, not all lambda abstractions are closures. Some of them might end up being compiled to labels in the function. Scheme uses syntactically recursive procedures to implement loops, after all. But Guile's CSE does poorly for lambda expressions that are actually labels. The reason is that lexical scope is not a dominator tree.

MLton hacker Stephen Weeks says it better than I do:

Thinking of it another way, both CPS and SSA require that variable definitions dominate uses. The difference is that using CPS as an IL requires that all transformations provide a proof of dominance in the form of the nesting, while SSA doesn't. Now, if a CPS transformation doesn't do too much rewriting, then the partial dominance information that it had from the input tree is sufficient for the output tree. Hence tree splicing works fine. However, sometimes it is not sufficient.

As a concrete example, consider common-subexpression elimination. Suppose we have a common subexpression x = e that dominates an expression y = e in a function. In CPS, if y = e happens to be within the scope of x = e, then we are fine and can rewrite it to y = x. If however, y = e is not within the scope of x, then either we have to do massive tree rewriting (essentially making the syntax tree closer to the dominator tree) or skip the optimization. Another way out is to simply use the syntax tree as an approximation to the dominator tree for common-subexpression elimination, but then you miss some optimization opportunities. On the other hand, with SSA, you simply compute the dominator tree, and can always replace y = e with y = x, without having to worry about providing a proof in the output that x dominates y. (i.e. without putting y in the scope of x)

[MLton-devel] CPS vs SSA

See my article on SSA and CPS for more context.

So that's one large source of lost CSE opportunities, especially in loops.

Another large source of lost opportunities is that the Tree-IL language, which is basically a macro-expanded Scheme, has the same property that Scheme does, that the order of evaluation of operands is unspecified.

Consider the base-case clause of my btree-cons above:

(let ((left *btree-null*) (right *btree-null*))
  (make-struct/no-tail btree head left right))

Now, *btree-null* is a toplevel lookup, that might have an unbound-variable effect. We should be able to eliminate one of them, though. Why doesn't the CSE pass do it? Because in Tree-IL, the order of evaluation of the right-hand-sides of left and right is unspecified. This gives Guile some useful freedoms, but little information for CSE.

This is an instance of a more general problem, that Tree-IL might be too high-level to be useful for CSE. For example, at runtime, not all lexical references are the same -- some are local, and some reference free variables. For mutated free variables, the variable is itself in a box, so to reference it you would load the box into a local and then dereference the box. CSE should allow you to eliminate duplicate loads of the box, even in the case that it can't eliminate duplicate references into the box.

conclusion

It is nice to be able to eliminate the duplicate checks, but not at any price. Currently the bootstrapping time cost is a bit irritating. I have other ideas on how to fix that, but ultimately we probably need to re-implement CSE at some lower level. More on that in a future post. Until then, happy hacking.

by Andy Wingo at May 14, 2012 05:07 PM

José Dapena

IwkMail, mixing WebKit Gtk+, Camel and JQuery Mobile

In the last few weeks, as part of my work here at Igalia, I’ve been playing a bit with the concept of hybrid applications. In this case, I’ve created a basic prototype of a mail application, with its user interface completely written using JQuery Mobile, and with backend code in C and GObject. The result is iwkmail.

Screencast of iwkmail in action

Though it’s a simple experiment, I’ve added some mail basic functionality, so I could try to catch as much as possible of real requirements for how  we could improve the developers WebKit+GNOME experience creating hybrid applications.

My first conclusion is that it’s surprisingly easy and fast to develop such applications. Second, I could reuse tons of source code and modules from my old projects. This approach surely provides a way to create cool GNOME applications, using the most fashionable web client technologies.

So, you’ll get:

  • Browsing messages
  • Read/unread flags
  • Deleting messages
  • Creating and deleting mail accounts.
  • Storage protocols supported: IMAP and POP.
  • For sending mails, we support SMTP. There’s support for an outbox holding the messages to be sent.
  • A plain text composer, allowing to add attachments.

The UI is completely written in Javascript + HTML, using JQuery Mobile.

The backend side is done using Camel library inside Evolution Data Server, so we rely on a library well tested for more than 10 years.  All the code related to this is implemented in C+GObject, and I reused a good set of code from Modest, the default mail client for Nokia N810 and N900. I’ve got involved on its development for 3 years, so that’s a bunch of code I know well enough.

For communication, I use the AJAX-like JSONP protocol, and custom SoupRequest URI scheme handlers. Basically I expose some methods as iwk:addAcccount, iwk:getMessage, etc, and arguments are passed as usual in a web request. The result I obtain from this calls is a JSON object with the results of the call. Simple, and works very well.

I’ve pushed the work on github: https://github.com/jdapena/iwkmail. Feel free to try it!

Oh, I guess it’s very obvious that I did not spend too much time thinking on the project name… So, anyone proposing something that matches the IM acronym (I don’t want to rewrite the class names!) would deserve a beer.

Last, lots of thanks to Igalia for giving me the opportunity to do this experiment. As usual, fun stuff to work with.

by jdapena at May 14, 2012 03:28 PM

May 11, 2012

Xabier Rodríguez Calvar

Sending emails in Harmattan with Qt/QML

In the context of a personal ad-hoc app (I will come to that later) that I wrote for my Nokia N9, I needed to send an email to a specific person with an attachment. After the first research at Harmattan APIs you come to QMessageService.

The first thing I did was writing Mixed QML/Qt object that I could instantiate from the QML code so that I could do something like:

Message {
    id: message
    from: "my@Address"
    to: [ "destination@Address" ]
    subject: "This is not Spam for sure!"
    body: "Trolled! Enlarge...!"
    attachments: [ "/a/path/to/an/attachment" ]
}

Button {
    onClicked: message.compose()
//    onClicked: message.send()
}

There we have an object with two send and compose methods, three string properties representing the from, subject and body and two string list properties representing the to and attachments (we leave the CC and BCC as an exercise ;) ). As I already explained how to create the objects with the properties in previous posts, I’ll go directly to the compose and send methods.

const QMessage Message::createMessage()
{
    QMessage message;

    message.setFrom(QMessageAddress(QMessageAddress::Email, m_from));
    QMessageAddressList toList;
    foreach (const QString &item, m_to) {
        toList.append(QMessageAddress(QMessageAddress::Email, item));
    }
    message.setTo(toList);
    message.setSubject(m_subject);
    message.setBody(m_body);
    message.appendAttachments(m_attachments);

    return message;
}

bool Message::send()
{
    QMessage message = createMessage();
    service.send(message);

    return true;
}

bool Message::compose()
{
    QMessage message = createMessage();
    service.compose(message);

    return true;
}

Easy, right?

Dancing Troll

If you want to be completely trolled stop reading here. If not, please continue.

That does not work, at least I could not make it work. I might be missing something, but I could not. I hooked to the signal and saw the state changes, that were going from sending to Ok and no email composer was showing up. No error was being returned either.

Finally, I got an easier solution by using Qt.openUrlExternally and mailto: directly from QML. You can use obscure parameters to compose the message the way you want. Example:

Button {
    onClicked: Qt.openUrlExternally("mailto:destionation@Address" +
                                    "?subject=Subject" +
                                    "&attach=/path/to/the/attachment" +
                                    "&body=Body")
}

That does the job and it is less complicated than creating a whole class. I leave the whole message class code in a pastebin in case somebody wants to try it or develop something from there in a platform where the QMessageService really works.

Ad-hoc program

My wife tracks all our finances using Home Bank and I needed an easy way to write down the cash expenses. I decided to code a simple program easying me to manage expenses by adding them to a list (and deleting them) and export them as CSV in order to be sent through email when she requested them. As the CSV and the expenses type were so ad-hoc, I decided not to complicate it and cable them in the code and database.

I don’t think it can be interesting to anybody, but I might end up uploading it to some git repo so that it can be maintained by someone else or even forked.

by calvaris at May 11, 2012 10:46 AM

May 10, 2012

Xan López

Japan Freedom Hackers: Assemble!

Turns out I’ll get to spend the next two weeks in Tokyo, starting next Sunday. It will be third time I visit this weird and fascinating place, but I’m still excited to be there again.

Some time ago, in another trip, I proposed anyone who might be reading me to meet up and talk about all things GNOME or WebKit. Turns out I met some interesting people that way (hi everyone from Caixa Mágica!), so let’s try again: if you are reading this, are in Tokyo, and would like me to talk to your friends/colleagues/whatever about GNOME or WebKit I’d be happy to do so. We can also improvise a hackfest or anything else we can come up with. In exchange I only ask of you to show me around (always better with a local) and an unwavering commitment to freedom and justice.

Drop me a line at xan AT gnome DOT org, or leave a comment in this space.

by xan at May 10, 2012 04:50 PM

May 09, 2012

Xavier Castaño

Master on Free Software. Web development module enrollment is now open

Since 2007, Igalia has been organizing a Master on Free Software. As part of this master, and in order to help students without the possibility of enrolling the whole master, Igalia offers the possibility of studying specific modules.

Specifically, Web development module has been open for enrollment until May, the 31th. If you are interested in it, more information can be found in Master on Free Software website.

As a summary, the web development module will deal with several technologies like PHP, Java, Ruby on Rails, PhoneGap, HTML,  Javascript, JQuery, etc. Hence, we recommend you to have a look to the program and join us for this course :) .

by xavier castano at May 09, 2012 10:25 AM

May 08, 2012

Xan López

Summer of Code, Web 2012 vintage

This year’s Summer of Code has already started, and Epiphany has been lucky enough to get two students assigned. Let’s see who they are and what they’ll be working on.

William Ting, Data Synchronization

William is a last year student of Computer Science at the University of Texas, Austin. He’ll be helping to alleviate a paradigmatic first world problem: I use Epiphany from so many computers that all my data is scattered around and I suffer a permanent pseudo-memory loss condition.

The battle plan is easy. We’ll reuse Firefox’s excellent design for a data sync protocol plus their free-to-use servers (we assume that’s what they were hoping for!), and will integrate the feature right into our browser. Since all the specs and implementation are open GNOME could host in the future a sync.gnome.org instance, but for now we leave that out of the scope of our summer project. Hopefully by 3.6 you’ll be able to optionally enable this functionality, cruise through the web from your tablet, bookmark that hilarious XKCD comic strip, and have it show up in your good old laptop just like that.

I’ll be mentoring this project myself, which was initially proposed by Igalia’s very own Joanmarie Diggs.

Yann Soubeyrand, Anti-phishing Support

Yann is a first year student at the École Nationale Supérieure d’Informatique et Mathématiques Appliquées de Grenoble. His task will be to solve a complicated problem that Epiphany has suffered for a long time: for most users the information provided in the URL entry is not enough to judge whether the page they are visiting is safe. The SSL or certification data is useless for most people, and by showing scary warnings about things they don’t understand at best you’ll train them to just click through to get to the content. To make things worse, most of the time those warnings do not actually indicate someone is trying to scam you, just that apparently setting up web servers correctly is difficult. So all in all, while useful, the information we currently show in the UI is really not that great for the 99% out there.

With this in mind, we’ll try to do the following: using the Google Safebrowsing APIs we’ll try to request authoritative information about the potential “phishiness” of the pages you visit. If we get a warning through this channel we can be confident about there being a security threat, so we’ll show a big, clear message on top of the web content. No jargon about outdated certs or VeriSign trying to take over the planet, just “Listen, our best people tell us this page is almost certainly not safe. Let’s not go there.”. We think this will significantly increase the safety of the browser without violating the user’s privacy, since Google’s API do not require you to disclose the pages you are visiting to validate them (magic? no, science).

Sergio Villar will be mentoring this project.

That’s it, let’s roll

That’s it for now. We’ll make sure to keep you updated about these and other developments in GNOME’s very own web browser. Thanks to GNOME for choosing our proposals, to Google for sponsoring Summer of Code again, and of course to Igalia for its continued support for GNOME and for allowing us to spend our time mentoring the fearless next wave. Happy hacking!

by xan at May 08, 2012 05:40 PM

Guillaume Emont

Video decoding in a sandbox

I would like to explain a bit the stuff I've been working on recently at Igalia. It is about playing with GStreamer and a sandboxing system to try and make the playback of untrusted media more secure. Hopefully writing this will be an occasion for me to get more distance and understand things better, and for others to give me feedback and ideas. Particularly, even though that is for me a field of interest, I do not claim to have any real expertise in security, therefore comments by people who know better would be gladly welcome.

This story started when I decided to have a look at chromium and its internals. It turns out that one very specific aspect of this application is its sandboxing system. In a nutshell, a sandbox is a virtual container in which untrusted programs can be safely run. In the real world, sandboxes are rarely perfect, but they are a significant security improvement over not using one. Chromium uses a sandbox to run its rendering engine (WebKit), which is basically the part that transforms the code of a web page into the graphical representation of it that you see on your screen. The rationale for running WebKit in a sandbox is not that it is untrusted code in itself, but rather that it is a big and complex project that is bound to have bugs, like all big and complex projects. On top of that, the input given to it is quite often data from untrusted sources, which could potentially be forged so that it exploits security bugs to do bad things to your computer and your beloved files. Now, with WebKit running in a sandbox, if a web page has been forged by an attacker to exploit a vulnerability in WebKit, the attacker will only have access to the sandbox environment, which means that it won't be able to do things like access the data on your computer, install software or connect to remote hosts.

As you might know, I like to play with multimedia things, and have hacked quite a bit on or around GStreamer. Therefore, I quite automatically thought of something else that might be worth running in a sandbox: demuxers and decoders. They are relatively big and complex pieces of software to which we regularly pass a whole bunch of untrusted data, would it be in a web context or a more traditional desktop or mobile context.

Fortunately, Julien Tinnes, a developer of the chromium sandbox for GNU/Linux made a stand alone version of it called setuid-sandbox, which can be used by other projects to easily sandbox any process.

Architecture

The way setuid-sandbox works is rather straightforward: there is a sandboxme command that needs to be installed setuid root. You run sandboxme my_command and then from inside my_command, you first set up the file descriptors that you will need (being careful not to put there anything that could allow to escape the sandbox, more on that later), and then you call the provided chrootme() function, which will tell the sandboxme process to restrict the privileges that my_command has (e.g. it can still read and write on the fds that it has open, but it cannot open new ones).

Here is how I organised my integration of setuid-sandbox into GStreamer. What I want to do for now is to put what I think are the "most dangerous" parts (demuxing and decoding) in the sandbox, while letting the other components (mainly source and sinks) outside of the sandbox (for now at least). I decided to create a small program (called gst-decoder) that receives the original muxed and encoded video stream and outputs the decoded video and audio buffers. gst-decoder needs 3 channels of communication with the "controlling" process outside the sandbox (which is called the broker):

  1. one to pass the original stream from the source element in the broker to gst-decoder
  2. one to pass the video buffers from gst-decoder to the video sink element in the broker
  3. one to pass the audio buffers from gst-decoder to the audio sink element in the broker

In the future, more channels for subtitle support or other features could be desirable.

Since I am lazy, I wanted to use off the shelf GStreamer elements to handle these communication channels. For the cases explained above, that would be:

  1. the fdsink element on the broker side, and the fdsrc element in the sandbox
  2. shmsink (in gst-decoder) and shmsrc (in the broker)
  3. same elements as above

Since I expect other people to be equally lazy^W^W^Wwant their life to be made easier, my goal is to try and have this reasonably integrated in GStreamer, and easy to integrate in applications. For that, my best idea so far was to make a sandboxedecodebin element that, from the outside, works like decodebin or decodebin2, at least for simple cases: it has a sink pad that can take any format you would throw at decodebin, and it has an audio and a video source pads that output the decoded result. In the future, it might or might not be a good idea to try to integrate the "sandboxed" functionality in decodebin directly.

I implemented sandboxeddecodebin as a subclass of GstBin, and it has the following flow inside it:

fdsink -> [gst-decoder] | -> shmsrc (video) -> gdpdepay
                        | -> shmsrc (audio) -> gdpdepay

Note that gst-decoder is an external (sandboxed) process, and not a GStreamer element like the other entities of this data flow graph. The sink pad of fdsink and the source pads of the two gdpdepay elements are exported by sandboxeddecodebin through ghost pads, which provides a decodebin-like interface.

The gst-decoder program basically runs a pipeline that looks like that:

fdsrc ! decodebin2 name=decoder
decoder. ! video/x-raw-yuv;video/x-raw-rgb ! gdppay ! shmsink (video)
decoder. ! audio/x-raw-int;audio/x-raw-float ! gdppay ! shmsink (audio)

and it also makes sure to get the privilege dropped at the right time, which is discussed below.

When to drop privileges?

The ordering of operations needs to be thought carefully to combine GStreamer, and these elements in particular, with setuid-sandbox. Each of them brings its own set of conditions.

For setuid-sandbox, inside the sandbox (in gst-decoder):

  • before we call chrootme(): we can open new fds and do a lot of nice initialisation, and we don't want to parse any untrusted data
  • after we call chrootme(): we can't open new fds any more, or do similar initialisation tasks, but we can work on the data we received.

GStreamer has several states in which an element can be, with some rules on what should be done in which state. From the design documentation, the states are defined as follow:

  • NULL: This is the initial state of an element.
  • READY: The element should be prepared to go to PAUSED.
  • PAUSED: The element should be ready to accept and process data. Sink elements however only accept one buffer and then block.
  • PLAYING: The same as PAUSED except for live sources and sinks. Sinks accept and rendering data. Live sources produce data.

In particular, the elements that interest us here behave in the following way:

  • shmsink is responsible for the creation and destruction of the shared memory object and the associated control socket and creates them when going from NULL to READY and destroys them when going from READY to NULL. Since shmsink is used from inside the sandbox, this means that the state change NULL to READY needs to happen before chrootme(). This also means that it won't be able to clean up properly the shared memory object and the control socket.
  • fdsrc doesn't create nor destroy the fd it uses, so that can be done separately. Moreover, in the case of stdin, we leave that responsibility to the system.

And quite obviously, we want gst-decoder to handle buffers only after it has called chrootme(), so that it is ready to run potentially unsafe operations.

This is relatively easy: all we have to do is, in gst-decoder, to call chrootme() once we are in the READY state and before going to PAUSED.

Another issue with the privilege drop is that we use decodebin2 (things would be the same with decodebin), and it only loads the plugins it needs once it knows what kind of data it will have to decode. That is, it needs to load plugins after it has started to analyse potentially unsafe data. My solution to that is to preload all the installed plugins when gst-decoder starts, so that decodebin2 doesn't need any privilege to have access to the plugins it wants (they are already in memory).

This is obviously suboptimal in memory consumption. I can think of two ways to improve that:

  • use a white/black list of plugins to avoid loading plugins we are not likely to need (there are many things we're pretty sure not to need in gst-decoder, such as all sources and sinks or gnonlin)
  • use a separate typefinding sandboxed process that will determine what plugins are needed, then have gst-decoder take as argument the plugins that it needs to load before dropping privileges

Synchronising broker and sandbox

Another synchronisation issue is that the broker has to wait for the sandboxed process to be ready before interacting with it. As seen before, we have 3 channels through which they interact, and they are of two different types:

  • the pipe to which the broker writes, which points to stdin in the sandboxed process
  • the shared memory areas, and their associated control sockets created by the two shmsink

The first one is easy to synchronise: as long as the sandboxed process is not ready, it won't read on the pipe, and fdsink on the broker will just wait until it can write.

The second one is more complex: the shared memory areas are announced over the control socket when they are ready, so this part gets done correctly for free by shmsrc. But the control sockets need to exist when shmsrc tries to connect to them (this happens when going from READY to PAUSED). For now, my workaround is to sleep() for 2 seconds when sandboxeddecodebin goes from NULL to READY, after launching the subprocess. With this, the control sockets are very likely to be created when shmsrc goes from READY to PAUSED.

This is obviously very hackish , and I think I would prefer to use GFileMonitors to check when the sockets are created. Also, I don't know if it's better to do that in sandboxeddecodebin (blocking the switch to READY, but using that file monitoring instead of a sleep(), or going to READY asynchronously if that's possible?) or in shmsrc (in which case I think it should be optional and probably make shmsrc go to PAUSED asynchronously).

Making Preroll work

On the broker side, we have another tricky situation. We typically run a pipeline that contains all of this (the parts between angle brackets are outside of sandboxeddecodebin and given as examples):

<filesrc> ! fdsink (passes data to gst-decoder)
shmsrc (gets data from gst-decoder) ! gdpdepay ! <autoaudiosink>
shmsrc (gets data from gst-decoder) ! gdpdepay ! <autovideosink>

This pipeline is atypical in that it has a sink that is not really at the downstream end of it (fdsink, which sandboxeddecodebin uses to pass data to gst-decoder). Data would go through it, then through gst-decoder and its own pipeline, and then emerge back in the broker's pipeline in the shmsrc elements.

This is a problem at the preroll phase. Preroll is what usually happens when going to PAUSED: the sinks wait until they have a buffer to render before committing the state to PAUSED. The issue with our pipeline, is that the "real" sinks will only get the data they need to commit to the PAUSED state if fdsink lets the data through, but fdsink only passes data once it is in PLAYING state (apart maybe from one initial buffer). On top of that sandboxeddecodebin is a subclass of GstBin. By default, GstBin only changes to the next state (e.g. PLAYING) once all its elements have reached the previous one (e.g. PAUSED). This gives us a nice deadlock: the final (downstream) sinks are waiting for data to come to them to commit their change to PAUSED, GstBin is waiting for all its elements (including final sinks) to finish their transition to PAUSED before asking them to go to PLAYING, and fdsink is waiting to be asked to switch to PLAYING before it lets the data through (that the final sinks are waiting on). My workaround to solve this deadlock is to manually request fdsink to go to PLAYING when sandboxeddecodebin is switching to PAUSED. That way, fdsink is "one state ahead" of the rest, and lets the data go through. I haven't decided yet if it's a very ugly way of solving that issue or if it's an awesome clever hack. If you have an idea of a cleaner solution, feel free to suggest it in the comments!

Analysis of open file descriptors

Once the privileges have been dropped, the sandboxed process is very limited in what it can do, but it still can use all the fds that it has open, which might be a way for it to escape the limitations we want to put on it. For instance, imagine that the sandboxed process has an open fd on the device that contains your home directory (say, /dev/sda). By reading it, it can access all your data, even though the sandbox is designed not to let it open more files.

This precise example is very unlikely to happen in our case, but some less obvious fds could lead to ways to escape the sandbox. That is why I think it is necessary to analyse the file descriptors that are open in the sandboxed process and to try to understand the risks they bring.

I took a "snapshot" of the open fds of gst-decoder while it was decoding a video, and here is what it looks like:

guijemont@thirtytwo:~$ ls -lv /proc/5860/fd
total 0
lr-x------ 1 guijemont guijemont 64 2012-04-18 18:17 0 -> pipe:[8348338]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 1 -> /dev/pts/5
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 2 -> /dev/pts/5
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 3 -> anon_inode:[eventfd]
lr-x------ 1 guijemont guijemont 64 2012-04-18 18:17 4 -> pipe:[8348342]
l-wx------ 1 guijemont guijemont 64 2012-04-18 18:17 5 -> pipe:[8348342]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 6 -> socket:[8358884]
lr-x------ 1 guijemont guijemont 64 2012-04-18 18:17 7 -> pipe:[8359036]
l-wx------ 1 guijemont guijemont 64 2012-04-18 18:17 8 -> pipe:[8359036]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 9 -> anon_inode:[timerfd]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 10 -> /run/shm/shmpipe. 5860.    0
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 11 -> socket:[8358886]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 12 -> socket:[8358887]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 13 -> socket:[8358888]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 14 -> /run/shm/shmpipe. 5860.    1
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 15 -> socket:[8358890]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 16 -> socket:[8358891]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 17 -> socket:[8358892]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 18 -> socket:[8358893]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 19 -> socket:[8358894]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 20 -> socket:[8358895]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 21 -> socket:[8348346]
lrwx------ 1 guijemont guijemont 64 2012-04-18 18:17 22 -> socket:[8348347]

I used the "usual suspects" (strace and gdb) to look further into this and understand where each fd comes from, and try to get an idea of how necessary it is and of how much of a risk it brings.

  • O: that is stdin, and it is the pipe I create when starting sandboxme gst-decoder. Also, it is read only. I don't think an attacker could do much with this, and we need it anyway.
  • 1 and 2: stdout and stderr, plugged to the pseudo tty where my test gst-launch command was running. This is clearly not necessary, and could be exploited for privilege escalation if there's a bad bug somewhere in devpts. I modified the code to make stdout and stderr point to /dev/null instead when gst-decoder is launched. There is an environment variable that can prevent that from happening when one wants to see the debug messages that are output by gst-decoder.
  • 3: This is an event fd used by the GMainContext. I suspect that at least a few of the components we run to decode our stuff needs a GMainLoop, and therefore a GMainContext. And I don't think this is very dangerous, though I don't know much about the complexity and safety of the event system.
  • 4 and 5: this is a pipe used by the GLib unix signal code. Both ends of the pipe are inside the sandbox, so I don't think this would be much of a problem.
  • 6 and 21: shm area control socket for audio. There is one fd created by socket() that is bound to the right temporary file, then another fd is created by accept() when the broker connects. We definitely need that if we want to use shm, which I think we do for performance reasons (I did not run benchmarks though).
  • 7 and 8: pipe open by some code in /usr/lib/frei0r-1/facedetect.so when it is g_module_open()'ed. I don't think we need that at all, and it might be a good motivation to try and not load all plugins. A limited risk though, since both ends of the pipe are inside the sandbox.
  • 9: a timer fd opened in the same conditions as the pipe of fds 7 and 8 (by frei0r's facedetect). This one definitely looks like an unnecessary risk, though I don't know how much of a risk it actually is.
  • 10 and 14: these are the shared memory areas (one for audio, one for video), so I think we definitely want them. The alternative would be to use regular sockets instead to pass the buffers, but I fear it might cost us much in performances for little added security, though this issue could deserve more investigation.
  • 11, 12, 15, 16, 17, 18, 19 and 20: these 8 fds are actually 4 socket pairs, with each time both ends inside the sandbox. They are all created by gst_poll_new(), by the following pieces of code:
    • shmsink in gst_shm_sink_start(). It does that twice: once for audio, once for video.
    • fdsrc in gst_fd_src_start().
    • the system clock (in gst_system_clock_init(), via gst_poll_new_timer()).
  • 13 and 22: shm area control socket for video. There is one fd created by socket() that is bound to the right temporary file, then another fd is created by accept() when the broker connects. We definitely need that if we want to use shm, which I think we do for performance reasons (I did not run benchmarks though).

Play with it!

You can check out the code from its github repository, instructions are available here.

by guijemont at May 08, 2012 09:01 AM

May 06, 2012

Felipe Erias

Hello, Planet GNOME. Hello, CHI2012.

My blog has just been added to Planet GNOME, so let this post be my way to say that I am very happy to join the fine people there (including several colleagues at Igalia).

This week I will be attending the CHI2012 conference in Austin, TX.  This is the main conference on human-computer interaction and UX design. I will write a long recap once it is over, with special attention to those bits that may be interesting to GNOME and other work that we are carrying out at Igalia, and also to things that are just too wonderful, eye-catching or plain weird to miss.

by femorandeira at May 06, 2012 12:27 PM

May 02, 2012

Adrián Pérez

Recipe: Fixed number of workspaces in GNOME 3.x

Type this in a terminal (change 4 to the number of desired workspaces):

gsettings set org.gnome.desktop.wm.preferences num-workspaces 4
gsettings set org.gnome.shell.overrides dynamic-workspaces false

Note: I have only checked this with GNOME 3.4 — YMMV :)

by aperez at May 02, 2012 01:32 PM

April 28, 2012

Xabier Rodríguez Calvar

Painting video with GStreamer and Qt/QML or Gtk+ with overlay

As part of my work at Igalia I had to work with video and GStreamer for some years. I always used Gtk+ for that so when I needed to do things with Qt and QML, things were different. In my projects I always used pure GStreamer code instead of the Qt bindings for GStreamer because at the moment those bindings were not ready or reliable.

I know two ways of painting video:

  • Overlay way, with a window id and so on
  • Texture streaming

I might write later about texture streaming, but I will focus now on overlay.

Painting

The first way means that you need from your graphical toolkit a window id. That window id is asked by the video sink element in a very special moment and you need to provide it in that moment if you have not provided it before. For example, if you are using playbin2 and you already know the sink you want to use, just instantiate your sink and set the window id at that moment with gst_x_overlay_set_window_handle and set the sink to the playbin2 element by setting the video-sink property.

If you are not using playbin2 and for example you are using GStreamer Editing Services, you cannot use a property because currently there is no one and need to use a more complicated method. I already reported the bug with its patches and hope that they apply them as soon as possible to improve compatibility with playbin2 because the way it is now is a bit inconsistent with the rest of GStreamer code base.

Both Qt and Gtk have now client side windows, which means that your program window has only one X window and it is the toolkit that decides which widget is receiving the events. The main consequence is that if we just set the window id, GStreamer will use the whole window and will paint the video over the rest of our widgets (it does not matter if QML/Qt or Gtk+) and you’ll get very ugly effects. To solve that, you need to set the render rectangle, which are the coordinates (relative to the X whole X window) where you want to paint your video. You need to do that just after setting the window id with gst_x_overlay_set_render_rectangle.

If you do not set your window handle and your render rectangle before the pipeline begins to move, it will ask you about that with the prepare-xwindow-id GstMessage, but this message can happen inside the GStreamer threads and it cannot wait until the main loop runs, it needs the information at that very moment, so you need to connect to the synchronous bus handle. GStreamer has a good example at the GstXOverlay documentation about how to do that. To use the callback in C++, you need to declare a static method and pass this as user data parameter, then you can behave almost as having a normal object method. This is the most common solution used in the GNOME world and fits perfectly with the Qt framework too.

The code to get the window id and render rectangle in Gtk+ would be something like:

GdkWindow *gdk_window;
gdk_window = gtk_widget_get_window(your_widget);
/* as sink you can use GST_MESSAGE_SRC() if you are waiting
    for the prepare-xwindow-id message */
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(your_sink),
                             GDK_WINDOW_XID(gdk_window));
/* do your maths about your coordinates */
gst_x_overlay_set_window_handle(GST_X_OVERLAY(sink),
                                x, y, width, height);

In Qt, if you are using common widgets, you could use something like:

WId winId = QApplication::activeWindow()->effectiveWinId();
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(your_sink),
                             winId);
/* do your maths about your coordinates */
gst_x_overlay_set_window_handle(GST_X_OVERLAY(sink),
                                x, y, width, height);

If you are using a QGraphicsScene you would do something like:

/* to get the view you could do something like this
    (if you have only one or will to mess things up):
QGraphicsView *view = your_scene.views[0];
*/
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(your_sink),
                             view->viewport()->effectiveWinId());
/* do your maths about your coordinates */
gst_x_overlay_set_window_handle(GST_X_OVERLAY(sink),
                                x, y, width, height);

If you are using QML, you would have a very similar approach to the last snippet, because as you should have a QDeclarativeItem, it has a scene() that you can use, to have something like QGraphicsView *view = scene().views[0]; (of course, assuming that you have only one view, which is the most common case).

Overlaying stuff

Some times it is nice do put your controls on top of the video by covering part of the image. It would be like having the video as the background of a canvas where you draw some other widgets. Some GStreamer elements give you the possibility of doing a trick to do this, which is using a colorkey for your background and painting whatever you want on top of that as long as it does not include that colorkey. Some elements like xvimagesink or omapxvsink (used in the Nokia N9 and N950) have the colorkey property that you can read and set. If you are not planning to overlay anything, you can forget about this, but if you do, you need set a color key to the sink and use that color to paint the background of your widget and a good moment is also when setting the window handle:

g_object_set(sink, "autopaint-colorkey", FALSE,
             "colorkey", 0x080810, NULL);

Why do I unset the colorkey autopainting? Because I do not want GStreamer to mess my widget painting.

And more important: Why did I use 0x080810? Because it is a dark color, close to black, but it is not black. Pure black can be dangerous as it is commonly used in themes when painting widgets so you would be getting ugly artifacts. Some people recommend magenta (0xFF00FF) as it is supposedly a color that does not exist in nature (citation needed). I would not do it for several reasons:

  • You will need to synchronize your painting very well to avoid seeing the colorkey
  • If you respect aspect ratio you will see it for sure, because you (or the sink if it is automatic) paint the backgound and the sink draws the image by leaving some empty space.
  • It does not behave well with blendings, as you blend from your widget color to the background, which is the colorkey

Advice: do not mess with colorkey and omapxvsink. Though it is supposed to be writable, it is not and it always uses 0x080810.

Aspect ratio

There are two kind of people:

  • The ones that want to use all the pixels of their monitor/TVs and like damaging their brain with distorted images.
  • The ones that like to see a correctly dimensioned image with some bars giving you a better impression of what was recorded.

As you can guess I belong to the second group.

There are some sinks that do that automatically for you by setting the force-aspect-ratio property, like ximagesink and xvimagesink but there are other that does not and omapxvsink is an example. It is not a big problem but forces you to work a bit more when you select the render rectangle. For that you need to know the video size, which you cannot know until the pipeline is running, which forces to to hook to the GST_MESSAGE_ASYNC_DONE, or in the case of playbin2, you already have the video size when getting the prepare-xwindow-id message. An example to get the video size would be:

GstPad *pad;
GstCaps *caps;
GstStructure *structure;
int width, height;

pad = GST_BASE_SINK_PAD(sink);
caps = GST_PAD_CAPS(pad);
g_return_if_fail(caps && gst_caps_is_fixed(caps));

structure = gst_caps_get_structure(caps, 0);
gst_structure_get_int(structure, "width", &width);
gst_structure_get_int(structure, "height", &height);

/* some videos define a pixel aspect ratio, meaning that the
   video pixel could be like 2x1 copared to a squared pixed
   and we need to correct this */
if (gst_structure_has_field(structure, "pixel-aspect-ratio")) {
    int par_n, par_d;
    gst_structure_get_fraction(structure, "pixel-aspect-ratio",
                               &par_n, &par_d);
    width = width * par_n / par_d;
}

/* trick: some sinks perform better with multiple of 2 */
width &= ~1;
height &= ~1;

by calvaris at April 28, 2012 11:58 PM

April 21, 2012

Jacobo Aragunde

LibrePlan nas XI Xornadas Libres

Unha breve nota para comentar que LibrePlan vai estar nas próximas Xornadas Libres, organizadas por GPUL na Facultade de Informática da Coruña. Vou ter ocasión de voltar á facultade para presentar a ferramenta e, con sorte, volver a ver algunhas caras coñecidas.

O meu turno é o martes 24 ás 18:00, pero non perdades ocasión de asistir tamén a outras charlas. ¡Véxovos alí!

by Jacobo Aragunde at April 21, 2012 06:11 PM

April 20, 2012

Joaquim Rocha

First presentation of Skeltrack

I spent the first half of this week in the beautiful city of Évora, where I was born. The occasion was the Semana da Ciência e Técnologia (Science and Technology Week) of the University of Évora to which I was invited.
I also ended up giving the organization a hand by asking Thomas Perl (the restless mind behind gPodder) and Lucas Rocha (well known GNOME developer now using his powers in Mozilla) who kindly accepted.

Having participated in the organization of events during the University, I’m always happy to see these initiatives taking place.
It was also great to spend a couple of days with the folks at my University and meet with old friends.

About the talks, Thomas gave an overview of gPodder and the infrastructure used to manage the project. Lucas gave a really nice talk about what Mozilla is, what it does and why you should care; because of it, I ended up installing Firefox Mobile nightly build for Android and it has improved a LOT.
My friend Luís Rodrigues (no blog because he’s a badass) talked about CERN, where he works. What an amazing place! He talked about how much CERN uses Python and Django to manage their data. As a Python lover, this makes me really happy.

This was also the first time I presented Skeltrack, my latest creation inside Igalia. Presenting such an algorithm is not an easy job so I took mental notes about what to improve the next time (which will be at LinuxTag) but I was happy that people made good questions about it.

I’d like to thank to the AAUE (Students Association) for the great time we all spent in there.

Presentation slides :

by Joaquim Rocha at April 20, 2012 09:40 PM

Felipe Erias

Sketching Butaca: IMDB on a tablet

Butaca is an application for the N9 developed by Simon Pena, hacker at Igalia. It is meant to be a companion to film lovers, providing information about movies, actors, directors… and even showtimes near you. It uses The Movie Database and Google Showtimes as backends.

As a design exercise, I started thinking some time ago about how we could port Butaca to a tablet form factor. As usual, this was the tool selected to help my thinking and get started in the design:

Notebook and pen

My basic idea was to keep the current presentation in pages, replacing the Back button with a horizontal navigation that would let you move back and forth along your history. The pages that you have seen are on your left; the “forward” ones are to the right, along with shortcuts to launch each of the main sections of the application.

To illustrate this, I drew a few mockups with Inkscape. This is one of them:

Butacka mockup

This helped in visualizing the solution, but important questions had not been quite answered yet. Would this idea really work on a tablet? Would it look nice? Does it really make sense to structure navigation history in this way? I might have tried to build a functional prototype, but prototypes are used to confirm decisions rather than raise questions. It is important to avoid committing too soon to a particular design, before the space of possible solutions has been fully explored. What was needed at this stage was something else, something tentative and exploratory. What was needed was a sketch.

Sketches are cheap, disposable, quick. So, I took a bunch of screenshots of the N9 application and joined them together with just ~160 lines of QML, in a sort of interactive collage. This method would work just as well with nice ad-hoc mockups, but those take more time and the point was to keep it quick. Igalia had provided me with a WeTab running GNOME 3, so I just had to load my little application on it and take the following video:

(direct link to video in Vimeo; sorry for the quality, the WeTab’s screen is terribly reflective)

Now, that is a better way to get the point across, isn’t it?

The take-home lesson here is that trying out ideas is important. There are techniques that assist us in creating interactive sketches quickly, which can be very useful when we need to explore ideas and build on them to generate new ones. Furthermore, a sketch can be a great communication tool, as I hope to have shown with the preceeding video.

by femorandeira at April 20, 2012 05:13 PM

Manuel Rego

LibrePlan is learning new languages: Salut, hoi, cześć!

We’re really happy to see that with every new release LibrePlan project is translated into new languages.

In LibrePlan 1.2.2 two new languages appeared:

  • French: In the past some people had already asked about French translation and finally this language was available for them. The work was initially started by Stephane Ayache and Guillaume Postaire, but finally Philippe Poumaroux did the final effort to complete the translation in order to have French supported 100%.
    LibrePlan screenshot in French

    LibrePlan screenshot in French

  • Dutch: This translation was done by Jeroen Baten, who is also participating in the LibrePlan community (for example he sent an script to connect JIRA with LibrePlan).
    LibrePlan screenshot in Dutch

    LibrePlan screenshot in Dutch

In the last version published yesterday, LibrePlan 1.2.3, again a new language has been included:

  • Polish: This time it was the Polish language provided by Krzysztof Kamecki.
    LibrePlan screenshot in Polish

    LibrePlan screenshot in Polish

For the future releases it seems that Czech language will be available too as you can check in Transifex.

We’d like to publicity thank the work done by our translators, that is allowing more and more people use LibrePlan without any language barrier. You guys rock! :-)

Finally, if you miss your language or want to improve, help or contribute in any of the current ones, the process is as easy as join Transifex and start to translate there.

PS: Transifex guys accepted my mini patch to improve the projects timeline RSS feed. Now you can be subscribed to it and it won’t be updated until there is any new translation or change in the project.

by Manuel Rego Casasnovas at April 20, 2012 10:45 AM

April 19, 2012

Jacobo Aragunde

LibrePlan 1.2.3. Go!

Today we are releasing the latest version of LibrePlan, numbered 1.2.3. The star of this release is the addition of the money cost monitoring system implemented by my team mate Manuel Rego, but there is a number of fixes added since the last release only one month ago, impacting small bugs, stability and performance.

The team is working hard to keep polishing the tool with the feedback of our users, while we work in new features for the next major release. We have some nice charts with new performance indicators, have improved the behaviour of the WBS table, and we keep working on other items in our roadmap. We had to delay the release date, but it’s worth waiting; meanwhile, download and try this new version!

We are building a more polished and stable planning tool day by day. Congratulations to all the members of LibrePlan community!

by Jacobo Aragunde at April 19, 2012 05:52 PM

April 17, 2012

Xabier Rodríguez Calvar

Aura

As my colleague Víctor at Igalia has said before in his post, Aura was released to the Nokia Store. Miguel, Víctor and I are quite happy with the result achieved with this app, which intention was to be kind of a port of the Cheese application of the GNOME platform to be used in the N9 or N950 Nokia phones.

The apps allows you to use both cameras (front and principal) to record videos, applying a lot of funny effects (a subset of the GNOME Video Effects) and changing them during the recording. Being Nokia a Finnish company, we decided to name the app after a Finnish Cheese to both honor the GNOME Cheese application and Finland ;)

You can download the app from the Nokia Store where we already got more than 6000 downloads and 100 reviews with a quite good average rating.

You have an example recorded by me with my own phone using the Historical effect and uploaded to Youtube:

And you have even already other videos uploaded to Youtube talking about how Aura works. This one is from a brazilian guy (obrigado!) for FaixaMobi and shows more effects:

Of course, being it free sofware you can also compile it yourself with the code at GitHub and do not be afraid of contributing! The technologies we used were the camerabin element of GStreamer and Qt/QML for the interface where we have the following components:

Aura components UML diagram

  • Main view (aura.qml) with the main interface
  • Controller, which is a mixed QML/C++ object allowing to control the pipeline.
  • Pipeline is a C++ object used by the controller to encapsulate the GStreamer code.
  • PostCapture is also a mixed QML/C++ object that opens the gallery application to show the recorded video and gives you the oportunity of sharing it, deleting it and so on. It uses a C++ controller loaded as a singleton to the context to do some stuff that can only be done in C++. Of course, you can open Gallery yourself and the videos will show up there.
  • EffectManager is a C++ class to load and manage the Effects, which is another C++ class defining how the effect must be applied.
  • Effects (Effects.qml) is a QML component to show the different effects, both software and hardware that Aura can apply. It uses the EffectManager (through the context) to load them and the Controller to apply them.
  • About view (AboutView.qml) is a rework of something done by my colleage Simón Pena and adapted to be used in Aura (Kudos!). It also uses a small AboutViewController to open a Nokia Store URL with the application instead of the browser.
  • ResourceManager is a C++ class used by the Controller to request the proper permissions to record the video.

by calvaris at April 17, 2012 04:23 PM

April 12, 2012

Joaquim Rocha

OCRFeeder 0.7.9 released

Last OCRFeeder‘s release had an important new feature which was the detection of changes in the configuration of OCR engines. However, I was very busy the last couple of months developing other cool stuff for Igalia, so, I ended up not testing this feature thoroughly (and I even warned users about that in my last post).

Fortunately, OCRFeeder has some users and contributors who did test it and warned me about some issues, which should be solved in this release.

Take a look at the short list of changes if you wanna see what’s solved and enjoy OCRFeeder.

Source Tarball
Git
Bugzilla

by Joaquim Rocha at April 12, 2012 08:09 AM

April 10, 2012

Víctor Jáquez

Aura

In the last weeks Miguel, Calvaris and myself, developed an application for the N9/N950 mobile phone and we called it Aura.

Basically it uses the device’s camera (either the main one or the frontal one) for video recording, as a normal camera application, but also it exposes a set of effects that can be applied, in real time, to the video stream.

For example, here is a video using the historical effect:

Aura is inspired in the Gnome application, Cheese, and it uses many of the effects available in Gnome Video Effects.

The list of effects that were possible to port to the N9/N950 are: dice, edge, flip, historical, hulk, mauve, noir/blanc, optical illusion, quark, radioactive, waveform, ripple, saturation, shagadelic, kung-fu, vertigo and warp.

Besides of these software effects, it is possible to add, simultaneously, another set of effects that the hardware is capable, such as sepia colors. These hardware capabilities do not impose extra processing as the software effects do.

Because of this processing cost, imposed by the non-hardware video effects, Aura has a fixed video resolution. Otherwise the performance would make the application unusable. Also, we had a missing feature: the still image capture. But, hey! there is good news: Aura is fully open source, you can checkout the code at github and we happily accept patches.

Honoring Cheese, the name of Aura is taken from a kind of Finnish blue cheese.

We hope you enjoy this application as we enjoyed developing it.

by vjaquez at April 10, 2012 11:46 AM

April 03, 2012

Joaquim Rocha

Controlling GNOME 3 with your hands

Last week Igalia released an important piece of software called Skeltrack which, to put it simple, allows to retrieve the human skeleton joints from depth images. It had a good coverage from many important news websites and blogs and I received good feedback with kind words and even use cases I hadn’t thought of.

Still, one thing is to have the simple demo of drawing a sort of stick man from one’s joints like shown in the Skeltrack’s example video, another is to actually do something more useful with it. This is the way to check how reliable the library is, so Igalia has built a prototype that consists of controlling the GNOME 3 desktop or even playing some racing games using gestures that are interpreted from the positions of the joints that Skeltrack gives.

It uses one or both hands to control the mouse pointer, perform clicks, drag things around and it even simulates a pinch gesture which adjusts the zoom level. Hands can be also interpreted as if holding a steering wheel, making racing games so much fun.

The results are shown in the following video:

(direct link to video in Vimeo)

Just like pretty much everything we do at Igalia, this demo is also Free Software, so you can get its code from GitHub (check the README to see what the gestures are and what they do), tweak it to your needs or, if you need specialized help, you can always hire us.

by Joaquim Rocha at April 03, 2012 01:00 PM

April 02, 2012

Jacobo Aragunde

A brief update on PhpReport

It’s been a long time since the last post about this tool. It was the announcement of beta 2, and a lot of things have been done in the >50 patches committed since then. Let’s review and update the TODO file of the last release:

  • Features:
    • Screen to manage cities and calendars DONE!
    • Screen to manage compensation of extra hours. DONE!
  • Documentation:
    • Write the basic end-user documentation WORK IN PROGRESS

Besides, there are bug fixes and usability improvements. All these changes can be seen in action in the public demo site.

As you can see, there’s little left to do to announce the final 2.0 release. But that won’t be the end of the road, but a milestone to take breath and keep coding.

by Jacobo Aragunde at April 02, 2012 11:06 AM

March 30, 2012

Alejandro Piñeiro

GNOME 3.4: Finally Orca+GNOME3

GNOME 3.4 is here!

Well, this is not really something new, but GNOME 3.4 was released. And as the release notes explains and Mathias Clasen advanced on his blog, one of the things improved was the screen reader support. On some of my old posts, I already mentioned how some stuff were slowly being added (like here and here). Although that work was also required, was mostly low level ATK stuff, and not really impressive from the POV of the user. After that work the outcome was GNOME Shell exposing some info through the accessibility technologies and Orca knowing that GNOME Shell is there. But it was mostly babbling.

For GNOME 3.4 we finally made a whole review of the GNOME Shell UI. Now most of those UI elements expose the proper combination of name, role (if the element is a button or not) and state (if a toggle button is checked or not). Adding the improvement on the stability and performance of the accessibility technologies (both at-spi2 and Orca), we have now something that we can ask Orca users to test. You can take a look to the result on this video:

[Video in Vimeo] [Full quality video in Ogv]

And now?

This is the first release of GNOME 3.4 with a proper Orca support, so the first one that we can proudly show to our users, so for sure we will get some feedback and some additional stuff to improve. But after all, GNOME has a bugzilla for a reason. During this cycle some users reported some issues with gdm, so we would require to review that part. For sure GNOME 3.6 will have a better accessibility support.

In the same way, don’t forget that GNOME Shell has other accessibility related features. Since GNOME 3.2 has a built-in magnifier, and now, with GNOME 3.4 it is fully configurable on the Universal Access Settings dialog. And for 3.6 it will have brightness and contrast functionality (something that Joseph Scheuhammer finished just after the code freeze) and hopefully focus-tracking.

Acknowledges and conclusions

This release shows how having people with some time to work on the accessibility stack can make things improve. Gtk accessibility is in a better shape thanks to Benjamin Otte. at-spi2 thanks to Mike Gorse. GNOME Shell magnifier thanks to Joseph Scheuhammer. Orca thanks to Joanmarie. Although GNOME 3.2 was an step over GNOME 3.0, the fact is it is more noticeable on GNOME 3.4, and it is mostly due the fact that for GNOME 3.2 (and perhaps 3.0) people were more busy on other stuff. Lesson learned: we need to find a way to keep people working on accessibility and getting more people.

Finally, I would like to mention that this is the first GNOME release since Joanmarie Diggs joined Igalia. Having her on Igalia and getting a release with a noticeable improvement on the accessibility support for GNOME Shell, and the performance and stability of Orca, is not a mere coincidence. Her experience, energy and motivation was a push to the work that Igalia has being doing.

by API at March 30, 2012 06:44 PM

March 29, 2012

Carlos García Campos

GNOME 3.4: WebKit2 and kinetic scrolling

The web at your fingertips

The GNOME Project has released GNOME 3.4, the second major release of GNOME 3. A lot of new features, UI improvements and other enhancements are included in this release, as well as important changes in the development platform. You can see all the details in the release notes.

One of the applications that has received a major revamp is Epiphany, the GNOME Web Browser, not only because of the beautiful new interface, but it also has significant improvements in performance and stability. If Epiphany is not your default browser, give it a try when you upgrade to GNOME 3.4. See Xan‘s and Diego‘s blog posts for more details of the new Web Browser.

WebKit2

GNOME 3.4 includes WebKitGTK+ 1.8.0, the first stable release that contains an initial WebKit2 GTK+ API. It’s disabled by default, though, since it’s still a preliminary version, so you need to build with –enable-webkit2 configure option. It’s already possible to try it out with Devhelp 3.4 which can be optionally built with WebKit2 using –with-webkit2 configure option. If the current API is enough to port your application, give it a try and let us know, you can use the webkit2 devhelp branch as a reference. We’ll provide a migration guide soon too.

Kinetic scrolling

GTK+ 3.4 has finally support for kinetic scrolling in GtkScrolledWindow. I’m very happy to know that the work made by Igalia during the GTK+/Meego Handset integration project has helped Carlos Garnacho to properly integrate kinetic scrolling in GTK+.

What’s next?

During the next development cycle, the Igalia WebKit team will continue to focus on making Epiphany even more awesome, with more UI improvements, and of course porting it to WebKit2.

by carlos garcia campos at March 29, 2012 09:33 AM

March 28, 2012

Manuel Rego

Money based cost monitoring system in LibrePlan

Last weeks in Igalia I’ve been working in a new feature that will be included in the next LibrePlan releases.

Summing up, the new feature consists of providing a method to monitor the cost of the different projects inside LibrePlan based on the money spent regarding to the original budget. Before in LibrePlan you could monitor the cost based in hours reported regarding to assigned hours, but it was not possible to do it checking the money spent.

Feature description

The result of this new feature from the users point of view has two main parts:

  • A new field called budget has been added together with the hours input for any task in the WBS view. Now, the user can specify the budget for every task.

    BTW, this field is also available in projects and tasks templates.

  • A new bar over the tasks in the Gantt view. This bar represents the money consumed at this moment comparing to the task budget. Then, you can check the progress of your tasks regarding the money you have reserved for it and the real amount spent.

In order to calculate the money spent in a task, the application uses the information in the work reports related to the cost categories of the different resources and the type of hours devoted to each task. Using all that entities, LibrePlan is able to calculate the how much money you have already spent to perform a concrete task.

Some screenshots

The new budget field can be edited from two places:

  • WBS view:

    New budget field in the WBS view

  • Details tab in task edition pop-up:
    New budget field on task edition pop-up

    New budget field on task edition pop-up

The new money cost bar can be enabled/disabled with a new button in the Gantt view:

Money Cost Bar in Gantt view

The information about the exact money spent can be read in two places:

  • Task tooltip in Gantt view:

    Information about budget and money spent on task tooltip in Gantt view

  • Imputed hours tab in task edition pop-up:

    Information about budget and money spent on imputed hours tab in task edition pop-up

About the implementation

As you know LibrePlan is entirely a free software project. Not only its source code is released under AGPL, but because of we do all the development in an open and public environment. Like for any other feature developed in the project you can read the analysis and implementation notes in the project wiki.

About the implementation issues, I’d like to highlight the new class MoneyCostCalculator which is in charge to calculate the cost of any task in terms of money. This class is only used for the new feature explained above, however in the future it could be useful to create some new reports, add money cost information to earned value chart or use in other parts of the application.

We hope you enjoy this new feature! Please don’t hesitate to contact us if you have any question about LibrePlan. And remember that Igalia offers a wide range of services around LibrePlan, just in case you need our help ;-)

by Manuel Rego Casasnovas at March 28, 2012 09:23 AM

March 26, 2012

Xan López

Web. It’s what’s for dinner.

GNOME 3.4 is around the corner, and with it a new version of its little web browser that could. This is for sure one of the most action packed releases in a long time, so let’s do a recap of the last 6 months of development.

New UI


The most obvious change at first glance is the refreshed UI, which was already covered in some detail in this blog post. Thanks to the hard work of the GNOME Design Team, the GNOME platform hackers and the Epiphany team we’ve got ourselves a completely new toolbar layout with elegant widgets (I particularly like the linked-style back/forward buttons), support for the new Shell application menu, the demise of our menubar and the debut of our ‘super-menu’ holding the less frequently used page specific actions. Not only the browser works better than ever, it now looks better than ever too.

New History

We have been talking about rewriting our history backend for many years now; to give just one example, as far back as 2007 we already had a Summer of Code project to try to fix some of its shortcomings, which were many. The old backend served us well for almost a decade, but it was showing its age: a difficult to understand legacy codebase, a bus factor of 1 and poorly scalable architecture that made storing more than a couple of weeks of browsing history a titanic task. Last year a crack team at Igalia was put together to fix this once and for all. Enter the new age:

  • Drop our XML based storage in favor of good ol’ SQLite. Many options were considered other than SQLite, and we could yet again change how things are done internally in the short term, but for the first step we decided to settle on a simple, trusted and performing technology.
  • Never block the UI. All actual history accesses are done in a special service thread which communicates its results when they are ready to the user interface. This way things will remain responsive and snappy, no matter how complex your queries are or how full to the brim your history is of non-stop reddit browsing.
  • Test it! User data is the most important thing the application handles, and losing your browsing history is the modern day lobotomy. Our new backend is thoroughly tested through unit tests, so your data is in good hands with us.

Thanks to the new backend we can now provide infinite history storage and instantaneous non-blocking search both in the URL entry and the history window, both long awaited features. Other than that, for 3.4 we tried to keep the UI as it was: one thing at a time. For 3.6, though, now that the we are beautiful on the inside, expect some surprises in how you interact with your history data.

New WebKit

As with every release, on time, we ship with the all new WebKitGTK+ 1.8. As usual there are way too many thing to list and they deserves their own blog post, but you can look forward to: the debut of the WebKit2 API (still experimental but with some modules already using it, like devhelp), WebGL, Accelerated Compositing, HTML5 History API, support for the last version of WebSockets, WebAudio, a rewritten favicon database class and loads and loads of bugfixes and improvements.

Less is more

A constant thought in my mind as a module maintainer is to focus our efforts in delivering the best experience we can given our available resources. I believe as a project, both GNOME and Epiphany, we are now facing the difficult choices successful software must go through at some point: stop trying to be everything for everybody, decide what you want to do and for whom, and try to do that really well.

Our new ongoing redesign is a great step in that direction, and I’m glad that we are finally focusing on what I think really matters. I believe 3.4 is our best release ever, with both cool new features and fixes for old major deficiencies, and things will only get better from here. And, a favorite pet peeve of mine, we did all that while massively cleaning up our codebase to make it cleaner and more hackable, a task without much glamour but a big payoff. Our last release, ignoring translations, icons and help files, comes with 214 modified files, 14,959 insertions and 24,341 deletions. For those keeping the score at home, that’s almost 10,000 lines less of code to maintain, read, patch and load!

Thanks!

Thanks to all the GNOME contributors that made possible this release, but a special thanks must go to Igalia for its continued support for Epiphany. We are not only the best WebKit consultancy around, but we are also putting our money where our mouth is by supporting web technologies in GNOME through its browser and beyond.

Work on 3.6 is already underway, so expect a lot more from your favorite webkittens 6 months from now. Until then, you can follow us on IRC, our mailing list, identi.ca, twitter, facebook or our new project page (wow!). Happy hacking!

by xan at March 26, 2012 08:35 PM

March 23, 2012

Xabier Rodríguez Calvar

Invoking Meego 1.2 Harmattan Gallery

As part of my work at Igalia I am writing an app to record some videos for the Nokia N9. I wanted to get them shown in the gallery so I tried the DBUS approach, that is something similar to what is explained here. The problem is the same they faced, meaning that I got gallery in foreground when it was not previously running, but not otherwise.

The solution to that was using libcontentaction. In order to get this working, first you need to get the vendor name in the tags of your pictures or videos, otherwise Tracker will not index them correctly and this solution can be useless.

With the following solution Gallery will be brought to foreground and show the desired file. Code would be something like:

using ContentAction::Action;

[...]

{
    Action action =
        Action::defaultActionForFile(uri,
            "x-maemo-nepomuk/device-captured-video");
    if (action.isValid()) {
        qDebug() < < Q_FUNC_INFO << "chosen action:" << action.name();
        action.triggerAndWait();
    } else {
        qWarning() << "could not file action for" << m_file;
    }
}

The mime type is one of the defined in the galleryserviceaction.desktop that you can find in the device. For images, you can also check the mime types in that file and maybe you do not need to specify it, but I have not tried this and let it to you. Please, comment me your findings.

by calvaris at March 23, 2012 12:42 PM

March 21, 2012

Simón Pena

Importing an OPML into Nokia N9 Feed Reader

As you know (and it's already reported), there's currently no way to import an OPML into the Nokia N9 Feed Reader application (see Harmattan Bug #159).

However, I noticed that when you open a feed link with the built-in browser, it launches the Feed Reader app, and asks you to subscribe to the feed. I guessed that it was communicating with the Feed Reader using D-Bus, so I dbus-monitored it, and that's what I found:

  1. First, the browser asks the application to subscribe to a given feed (here I'm asking the client to subscribe to my blog's feed):
    dbus-send --print-reply --dest=com.nokia.FeedReader \
    / \
    com.nokia.FeedReader.subscribeFeed array:string:"http://simonpena.com/blog/feed/"
  2. If the user accepts that, then the Feed Reader application requests the Engine to actually subscribe to the Feed. The nice thing is that, although you cannot (AFAIK) ask the client to subscribe to more than one feed at the time, you can ask the Engine to do it, so this actually works (requesting the engine to subscribe to my blog, Planet Maemo and Planet Igalia):
    dbus-send --print-reply --dest=com.nokia.FeedEngine \
    / \
    com.nokia.FeedEngine.subscribe \
    array:string:"http://simonpena.com/blog/feed/","http://maemo.org/news/planet-maemo/rss.xml","http://planet.igalia.com/atom.xml" \
    string:"rssatom"

From this point on, it should be quite straight forward to import an OPML into the Feed Reader application. You can use a QDomDocument to parse the OPML or use QML's XmlListModel to parse the OPML file.

XmlListModel {
    property string subTitle: ''

    query: subTitle ? "/opml/body/outline[@title='" + titleText + "']/outline": "/opml/body/outline"

    XmlRole { name: 'text'; query: '@text/string()' }
    XmlRole { name: 'title'; query: '@title/string()' }
    XmlRole { name: 'type'; query: '@type/string()' }
    XmlRole { name: 'xmlUrl'; query: '@xmlUrl/string()' }
    XmlRole { name: 'htmlUrl'; query: '@htmlUrl/string()' }
}

Then, you can use this to subscribe to the feeds using D-Bus:

static const QString DBUS_IFACE("com.nokia.FeedEngine");

void Controller::subscribeFeeds(const QStringList &feedList) const
{
    QDBusInterface dbusInterface(DBUS_IFACE,
                                 "/",
                                 DBUS_IFACE,
                                 QDBusConnection::sessionBus());

    dbusInterface.asyncCall("subscribe",
                            QVariant::fromValue(feedList),
                            QVariant::fromValue(QString("rssatom")));
}

I hope you find this useful :-)

by Simón at March 21, 2012 02:35 PM

March 20, 2012

Joaquim Rocha

Announcing Skeltrack

After being able to control the basic features of a Kinect device (or any time-of-flight camera), the next thing many users look for is skeleton tracking. Skeleton tracking means to easily retrieve different joints of the human skeleton from depth images.

The most famous solutions (or the only ones) to do so are the Microsoft Kinect SDK or the OpenNI framework. If you are looking for a Free software solution though, you are out of luck. Microsoft’s SDK, apart from obviously being close, does not even allow a commercial use of it which is something the OpenNI framework does but this is as far as the meaning of the word “open” in OpenNI goes… You cannot adapt/improve their code nor learn from it. To solve this problem, Igalia has just created Skeltrack.

Free Software Skeleton Tracking

Skeltrack is a Free and Open Source Software library whose goal is to provide easy to use human skeleton tracking.
Skeltrack’s implementation was based on a paper by Andreas Baak but, apart from other internal differences, it doesn’t use a pose database. This means that the skeleton joints extraction is based on mathematics and heuristics, no calibration pose nor pose database is needed.

It provides an asynchronous API written in GLib, supports single user tracking (one skeleton only) and tracks up to 7 joints currently: head, shoulders, elbows and hands.

Take a look at the video below to get an idea of what it can do:


(watch it in Vimeo)

How to use it

We took a more modular approach than the two projects mentioned above. This means that Skeltrack expects to be given a depth buffer (i.e. depth image from the Kinect) with nothing but the user on it as opposed to connecting directly to a Kinect device.
Still, three easy steps should be all that is needed for Skeltrack to be ready to use:
1) Use the GFreenect library we released a couple of months ago, connect to the depth stream signal and get the depth buffer;
2) If there are other objects (chairs, tables, walls, etc.) apart from the user, then these should be removed by performing background subtraction or by excluding everything that is out of a threshold;
2) Skeltrack performs some calculations that might be heavy depending on the machine and the buffer size so users should reduce the size of the buffer that is given to Skeltrack by using its dimension-reduction property as the reduction factor.

Take a look at the test-kinect example (shown in the video) shipped with Skeltrack where the steps above are implemented.
The documentation for the project is available here.

Skeltrack is in its early beginnings and we want to detect more skeleton joints and work on stabilizing the results so, its features and API might change in the future.

Feel free to get the code, file bugs and send patches at its GitHub repository.
Hopefully more people will contribute to it until we finally have a rock solid, easy to use, Free Software skeleton tracking library.

I need to thank Søren Hauberg who was kind enough to point me in the right direction when I needed.

by Joaquim Rocha at March 20, 2012 10:36 PM

March 19, 2012

Xabier Rodríguez Calvar

Mixed QML/C++ objects reloaded

Some days ago I was writing about how to have mixed QML/C++ objects in a QML application for Igalia, but I faced a problem with the code that I had written. And the problem was that I needed to receive some events and from the QML elements I was loading. Retaking that code:

#define QML_PATH "/path/to/the/qml/files/"

MyObject::MyObject(QDeclarativeItem *parent = 0) :
    QDeclarativeItem(parent)
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine,
        QUrl::fromLocalFile(QML_PATH "MyObject.qml"));
    QDeclarativeItem *rect =
        dynamic_cast(component.create());
    rect->setParentItem(this);
}

and being MyObject.qml something like:

Button {
    id: "myButton"
    text: "Do something cool"
}

The natural way of connecting that button to some slot you are writing would be something like:

MyObject::MyObject(QDeclarativeItem *parent = 0) :
    QDeclarativeItem(parent)
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine,
        QUrl::fromLocalFile(QML_PATH "MyObject.qml"));
    QDeclarativeItem *item =
        dynamic_cast(component.create());
    item->setParentItem(this);
    connect(item, SIGNAL(clicked()), this, SLOT(doCoolStuff()));
}

Even if you do this, you are not getting any event in the QML button you declare. It behaves as it were a label or whatever, but the key is the engine. The engine must live while you need the events of the QML component. And the easiest way of getting that done is adding the engine as a private class attribute:

#ifndef MYOBJECT_H
#define MYOBJECT_H

#include
#include
#include 

class PostCapture : public QDeclarativeItem
{
    Q_OBJECT

// ...

 private slots:
    void doCoolStuff();

 private:
    QDeclarativeEngine m_engine;
};
#endif

and of course removing the engine stack declaration from the constructor:

MyObject::MyObject(QDeclarativeItem *parent = 0) :
    QDeclarativeItem(parent)
{
    QDeclarativeComponent component(&m_engine,
        QUrl::fromLocalFile(QML_PATH "MyObject.qml"));
    QDeclarativeItem *item =
        dynamic_cast(component.create());
    item->setParentItem(this);
    connect(item, SIGNAL(clicked()), this, SLOT(doCoolStuff()));
}

Voilà.

Of course, if you need to connect to any element that is not the root element, you can always forward the signals and properties from the QML root object or just use the QObject::findChild method to access the right component.

by calvaris at March 19, 2012 05:41 PM

March 18, 2012

Joaquim Rocha

OCRFeeder 0.7.8

That’s right, one more release of OCRFeeder. If you’re wondering why so much time for apparently so little changes, it has to do with some super cool things I’ve been working on at Igalia, but you’ll know about that really soon.

This new release brings a few bug fixes such as:
* Fix recognition after using the Unpaper tool;
* Fix an Unpaper issue due to an nonexistent variable
* Prevent the version of Tesseract OCR engine from appearing in the recognized text

This last issue happened after an update in Tesseract which made it print “Tesseract Open Source OCR Engine v3.02 with Leptonica” to the standard output. Since the default way that the Tesseract engine is configured wasn’t discarding the text printed to the standard output, it would appear as part of the recognized text.

After a bit of discussion in the bug report, the conclusion was that OCRFeeder needed a way to detect the changes in the OCR engines’ configuration. This means this new version includes a way to check the needs for these updating the configuration and will warn the user about it once (on start-up). If it can update the engines’ configuration automatically it will say so and ask for confirmation, otherwise it will ask the user to change it manually and offer a way to open the OCR Engines Manager dialog.
The pictures below show what I just wrote:

OCRFeeder warnings

OCRFeeder warnings

(note that the first time you use this new version and since this feature wasn’t extensively tested, it might warn you even for engines that do not need a change; still, if it happens, it’ll be only once)

To see the entire list of changes and the amazing work of the GNOME i18n team, check out the NEWS file.

Source Tarball
Git
Bugzilla

by Joaquim Rocha at March 18, 2012 06:29 PM

March 16, 2012

Carlos López

Git: Copy a file or directory from another repository preserving the history

How to copy a file or directory from another GIT repository while preserving its history?

Internet is full of magic formulas each one more complex.

Here I’m proposing a much simpler and faster one that is to make a git format-patch for the entire history of the file or subdirectory that we want and then import it into the destination repository.

mkdir /tmp/mergepatchs
cd ~/repo/org
export reposrc=myfile.c #or mydir
git format-patch -o /tmp/mergepatchs $(git log $reposrc|grep ^commit|tail -1|awk '{print $2}')^..HEAD $reposrc
cd ~/repo/dest
git am /tmp/mergepatchs/*.patch

Simple and fast :)

by clopez at March 16, 2012 07:32 PM

José Dapena

Epiphany meets the web app stores

In last weeks, I’ve been taking a look at the web applications standards support in Epiphany, as part of my work at Igalia. Xan wrote about the Save as web application feature present in Epiphany 3.2, that is a base for very simple (and userful) web applications support in Gnome desktop.

To continue with this work, I’ve been investigating on adding support for some web app stores. So I’ve done an experimental implementation for Mozilla Open Web Apps (as in 2011 tech preview), Chrome Web Store hosted and packaged apps, and Chrome CRX-less apps.


Screencast using Chrome Web Store.

This is an experiment. Not supported, and it may actually stay out of official Epiphany. So there are lots of things not working at all. This is first a way to have a big number of apps to play with our application mode, and improve it. So no permissions check, URL’s match may be broken, many apps will fail to even log in… Did I say it is an experiment? Most obvious issues are related with this external links handling bug.

But, if you just want to play with it, just try my branch webapp in my Epiphany Github repository. By default, support is disabled, so you’ll have to enable these keys:

$ gsettings set org.gnome.Epiphany.web enable-chrome-apps true
$ gsettings set org.gnome.Epiphany.web enable-open-web-apps true

You can try with Mozilla Labs Apps Dir from 2011 tech preview and Chrome Web Store.

by jdapena at March 16, 2012 10:33 AM

March 12, 2012

Andy Wingo

the merry month of ma

or, from the department of self-inflicted injuries

Recently I saw a bunch of errors in my server logs. People were asking for pages on my web site, but only if they were newer than Thu, 08 Ma 2012 22:44:59 GMT. "Ma"? What kind of a month is that? The internets have so many crazy things.

On further investigation, it seemed this was just a case of garbage in, garbage out; my intertube was busted. I was the one returning a Last-Modified with that date. It was invalid, but client software sent it back with the conditional request.

Thinking more on this, though, and on the well-known last-modified hack in which that field can be used as an unblockable cookie, I think I have to share some blame with the clients again.

So, clients using at least Apple-PubSub/65.28, BottomFeeder/4.1, NetNewsWire, SimplePie, Vienna, and Windows-RSS-Platform/2.0 should ask the people that implement their RSS software to only pass a Last-Modified date if it's really a valid date. Implementors of the NetVibes and worio.com bots should also take a look at their HTTP stacks. I don't guess that there's much that you can do with an etag though, for better or for worse.

Previously, in a related department.

by Andy Wingo at March 12, 2012 08:27 PM

March 09, 2012

Teo Romera

Make Webex work in Ubuntu 11.10 64 bit

Today I wanted to attend a webinar put together by the people in The European IPR Helpdesk about Intellectual Property and Intellectual Property Rights. I plan to attend many others during the following weeks, because the topics are very interesting for companies exploring EU R&D funding programmes such as FP7. Here is the list of webinars for the first quarter of the year, have a look.

Igalia is currently involved in two FP7 project proposals submitted to the EC for evaluation and we plan to make part of a few more consortia for R&D projects soon. We are also looking for ways to start our own projects and get them accepted in national programmes and smaller European opportunities. We recently hired specialised staff and we seize training opportunities such as these IPR Helpdesk seminars.

The only drawback is that they are using Webex for these webinars. Webex is a solution for meetings that integrates chat, VoIP, VideoConferencing and desktop sharing. It is made by Cisco and it is not open source. There are some open source alternatives to Webex, like OpenMeetings and BigBlueButton, but they are not as popular.

Anyway, I was forced to use Webex and tried to enter the webinar only to find out that although I could join the event and chat to the host, I could not see the desktop that the speaker was sharing nor hear anything. I was stuck before the following error message:

“The Audio Device is Unaccessible Now”

After searching a bit on the web, I found dozens of posts and bug reports regarding this issue in different combinations of Ubuntu/Java/Firefox setups. None of them worked until I found this comment by someone called Steve on a blog post about making Webex work in Ubuntu 9.10 64 bit. The root of all problems is that Webex does not officially support 64 bit Linux. So part of the solution is having two separate Firefox/Java setups in your machine, one 64 bit and one 32 bit to use for Webex sessions. Even better, you can use Swiftfox for Webex and keep Firefox for your daily normal use.

Attending a webinar with Webex

So this is what I did:

  1. Install Swiftfox 32 bits
  2. Instal Java 32 bits
    • Go to http://www.java.com/
    • Download the self extracting file. The one that I got is: jre-6u31-linux-i586.bin
    • Grant execution permission for the file: chmod +x jre-6u31-linux-i586.bin
    • Execute it: sudo ./sh jre-6u31-linux-i586.bin
    • It will self-extract to a directory called: jre1.6.0_31
    • Copy that directory to an appropriate location, your home dir for example: cp  jre1.6.0_31 $HOME
  3. Make Swiftfox use the files in $HOME/jre1.6.0_31/
    • Go to /usr/lib/swiftfox/plugins/ and remove the following files if they exist: libjavaplugin_oji.so, libjavaplugin.so and libnpjp2.so
    • Create the following links to the matching files in $HOME/jre1.6.0_31/

With ln -s link_name $HOME/jre1.6.0_31/target_name:
libjavaplugin_oji.so -> /home/teo/jre1.6.0_31/plugin/i386/ns7-gcc29/libjavaplugin_oji.so
libjavaplugin.so -> /home/teo/jre1.6.0_31/lib/i386/libnpjp2.so
libnpjp2.so -> /home/teo/jre1.6.0_31/lib/i386/libnpjp2.so

Now you should have a Swiftfox/Java 32 bit setup (besides your normal Firefox 64 setup) that you can use to join Webex events. You can try that your setup by joining this test meeting. Be careful to actually launch Swiftfox when you need it and not just a new Firefox window, run it from the terminal with this command to make sure, as explained here:

swiftfox -P -no-remote

by Teo at March 09, 2012 07:34 PM

March 08, 2012

Andy Wingo

an in-depth look at the performance of guile's web server

What ho, ladies! And what ho, gentlemen! The hack is on and apace. Today, the topic is performance: of Guile and of its web server, in microseconds and kiloinstructions. Brew up a pot of tea; this is a long article.

the problem

I have been poking at Guile's web server recently. To recap, Guile is an implementation of Scheme. It is byte-compiled, and has a set of runtime libraries written in C and, increasingly, in Scheme itself.

Guile includes some modules for dealing with the web: HTTP, clients, servers, and such. It's all written in Scheme. It runs this blog you're reading right now.

To be precise, this web log is served by tekuti, an application written on top of Guile's web server; and actually, in this case there is Apache in front of everything right now, so you're not talking directly to Guile. Perhaps that will change at some point.

But anyway, a few months ago, this blog was really slow to access. That turned out to be mostly due to a bug in tekuti, the blog application, in which generating the "related links" for a post would always end up invoking git. (The database for the blog is implemented in git.) Spawning another process was slow. Fellow hacker and tekuti user Aleix Conchillo Flaqué fixed the problem a year ago, but it took a while for it me to finally review and merge it.

So then, at that point, things were tolerable, but I had already contracted the performance bug, so I went on to spend a couple months drilling down, optimizing Guile and its web server -- the layers below tekuti.

10K requests per second: achievement unlocked!

After a lot of tweaking, to the compiler, runtime, HTTP libraries, and to the VM, Guile can now serve over 10000 requests per second on a simple "Hello world" benchmark. This is out of the box, so to speak, if the master branch in git were a box. You just check out Guile, build it using the normal autoreconf -vif & & ./configure && make dance, and then run the example uninstalled:

$ meta/guile examples/web/hello.scm

In another terminal, you can connect directly to the port to see what it does. Paste the first paragraph of this and press return, and you should see the second part:

$ nc localhost 8080
GET / HTTP/1.0
Host: localhost:8080
User-Agent: ApacheBench/2.3
Accept: */*

HTTP/1.0 200 OK
Content-Length: 13
Content-Type: text/plain;charset=utf-8

Hello, World!

I should say a little more about what the server does, and what the test application is. It reads the request, and parses all the headers to native Scheme data types. This is strictly more work than is needed for a simple "pong" benchmark, but it's really useful for applications to have all of the headers parsed for you already. It also filters out bad requests.

Guile then passes the request and request body to a handler, which returns the response and body. This example's handler is very simple:

(define (handler request body)
  (values '((content-type . (text/plain)))
          "Hello, World!"))

It uses a shorthand, that instead of building a proper response object, it just returns an association-list of headers along with the body as a string, and relies on the web server's sanitize-response to produce a response object and encode the body as a bytevector. Again, this is more work for the server, but it's a nice convenience.

Finally, the server writes the response and body to the client, and either closes the port, as in this case for HTTP/1.0 with no keep-alive, or moves the client back to the poll set if we have a persistent connection. The reads and writes are synchronous (blocking), and the web server runs in one thread. I'll discuss this a bit more later.

You can then use ApacheBench to test it out:

$ ab -n 100000 -c100 http://localhost:8080/
Server Software:        
Server Hostname:        localhost
Server Port:            8080

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      100
Time taken for tests:   9.631 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      9200000 bytes
HTML transferred:       1300000 bytes
Requests per second:    10383.03 [#/sec] (mean)
Time per request:       9.631 [ms] (mean)
Time per request:       0.096 [ms] (mean, across all concurrent requests)
Transfer rate:          932.85 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       3
Processing:     1   10   1.7      9      20
Waiting:        1   10   1.7      9      20
Total:          3   10   1.7      9      20

Percentage of the requests served within a certain time (ms)
  50%      9
  66%      9
  75%     12
  80%     12
  90%     12
  95%     12
  98%     13
  99%     13
 100%     20 (longest request)

I give you the whole printout because I find it interesting. There's no huge GC pause anywhere. This laptop has an Intel i7-2620M 2.70GHz CPU. It was bought last year, so it's recent but not fancy. There are two cores, and so part of one core is being used by ApacheBench, and the whole other one used by Guile.

Of course, this is a flawed benchmark. If you really care about this sort of thing, Mark Nottingham wrote a nice article on HTTP benchmarking last year that shows all the ways in which this test is wrong.

However, flawed though it is, this test serves my purposes: to understand the overhead that Guile and its web server imposes on a web application.

So in that light, I'd like to take apart this test and try to understand its performance. I'll look at it from three directions: bottom-up (using low-level profiling), top-down (using a Scheme profiler), and transverse (profiling the garbage collector).

bottom-up: clock cycles, instructions retired

The best way to measure the performance of an application is with a statistical profiler. Statistical profiling samples what's really happening, without perturbing the performance characteristics of your application.

On GNU/Linux systems, we have a few options. None are really easy to use, however. Perf comes the closest. You just run perf record -g guile examples/web/hello.scm, and it records its information. Then you run perf report and dive into the details through the mostly pleasant curses application.

However, for some reason perf could not capture the call graphs, in my tests. My machine is x86-64, which does not include frame pointers in its call frames, so perhaps it was a naive stack-walking algorithm. The associated DWARF information does include the necessary stack-walking data.

Anyway, at least you can get a good handle on what individual functions are hot, and indeed what source lines and instructions take the most time. These lowest-level statistical profilers typically sample based on number of clock cycles, so they correspond to real time very well.

So much for measurement. For actually understanding and improving performance, I find valgrind's callgrind tool much more useful. You run it like this:

valgrind --tool=callgrind --num-callers=20 /path/to/guile examples/web/http.scm

Valgrind can record the execution of your program as it runs, tracking every call and every instruction that is executed. You can then explore the resulting log with the kcachegrind graphical tool. It's the best thing there is for exploring low-level execution of your program.

Now, valgrind is not a statistical profiler. It slows down and distorts the execution of your program, as you would imagine. Beyond those caveats, though, you have to keep two things in mind: firstly, that a count of instructions executed does not correspond directly to clock cycles spent. There are memory latencies, cache misses, branch mispredictions, and a whole host of randomnesses that can affect your runtime. Secondly, valgrind only records the user-space behavior of your program. I'll have more to say on that later.

If I run the "hello.scm" benchmark under valgrind, and hit it with a hundred thousand connections, I can get a pretty good idea what the aggregate behavior of my program is. But I can do better than big-picture, for this kind of test. Given that this test does the same thing a hundred thousand times, I can use valgrind's accurate call and instruction counts to give me precise information on how much a single request takes.

So, looking at the total instruction and call counts, and dividing by the number of requests (100K), I see that when Guile handles one request, the algorithmic breakdown is as follows:

instructions per requestpercentage of totalprocedurecalls per request
250K100(total)-
134K52.5bytecode interpretation-
47K18.5port buffer allocation1
18K7.2display1
7.6K3allocation within VM (closures, pairs, etc)83
7.2K2.84read-line5
3.6K1.40substring-downcase3
3.2K1.24string->symbol4
3.1K1.23accept1
2.7K1.06substring11
2.6K1.03string-index8
2.5K1.00hashq-ref14
23K9other primitives < 1% each-

Guile's ports can be buffered, like C's stdio FILE* streams, and the web server does turn on buffering. The 18.5% of the time spent allocating port buffers seems like a ripe place for optimization, but digging into it, almost all of the time within those routines is spent in the garbage collector, and most of that marking the heap. Switching to a generational collector could help here, but I'm not sure how much, given that port buffers are probably 4 KB each for input and output, and thus might not fit into a young generation. Marking from more threads at once could help -- more on that in some future essay.

There are some primitives that can be optimized as well, but with the VM taking up 52% of the runtime, and 23% for allocation and the garbage collector, Amdahl's law is against us: making the primitives twice as fast would result only a 15% improvement in throughput.

Turning Amdahl's argument around, we can predict the effect of native compilation on throughput. If Guile 2.2 comes out with native compilation, as it might, and that makes Scheme code run 5 times faster (say), then the 50% of the instructions that are currently in the VM might drop to 10% -- leading to an expected throughput improvement of 67%.

top-down: scheme-level profiling with statprof

But what is going on in the VM? For that, I need a Scheme profiler. Fortunately, Guile comes with one, accessible at the REPL:

$ guile --no-debug
> ,profile (load "examples/web/hello.scm")
%     cumulative   self             
time   seconds     seconds      name
 15.42      1.55      1.55  close-port
 11.61      1.17      1.17  %after-gc-thunk
  6.20      1.65      0.62  setvbuf
  4.29      0.43      0.43  display
  3.34      0.35      0.34  accept
  2.86      0.35      0.29  call-with-error-handling
  2.38      0.24      0.24  hashq-ref
  2.23      9.16      0.22  with-default-trap-handler
  2.07      0.67      0.21  build-response
  1.75      1.17      0.18  sanitize-response
...
Sample count: 629
Total time: 10.055736686 seconds (1.123272351 seconds in GC)

(I use the --no-debug argument to avoid some per-VM-instruction overhead imposed by running Guile interactively; see VM Hooks for more.)

Here I get a really strange result. How is close-port taking all the time? It's implemented as a primitive, not in Scheme, and Valgrind only thought it took 0.40% of the instructions. How is that?

To answer this, we need to remember a couple things. First of all, we recall that Guile's statistical profiler uses setitimer to get signals delivered periodically, after some amount of time spent on the program's behalf, including time spent in the kernel. Valgrind doesn't account for system time. So here we are seeing that close-port is indeed taking time, specifically to flush out the buffered writes. The time is really being spent in the write system call.

So this is good! We know now that we should perhaps look at tuning the kernel to buffer our writes better.

We can also use the profiling data counts to break down the time spent in serving one request from a high level. For example, http-read handles traversing the poll set and accepting connections, and tail-calls read-request to actually read the request. Looking at the cumulative times in the chart tells me that out of each request, the time spent breaks down like this:

microseconds per requestprocedure
100(total)
29poll and accept
16reading request
0request handler
12sanitize-response
8writing response headers
0writing response body
15close-port
20other

Of course, since this is statistical, there is some uncertainty about the whole thing. Still, it seems sensible enough.

transverse: who is doing all the allocating?

Often when you go to optimize a Scheme program, you find that it's spending a fair amount of time in garbage collection. How do you optimize that? The rookie answer to this is to try to patch the collector to allocate faster, or less frequently, or something. Veterans know that the solution to GC woes is usually just to allocate less. But how do you know what is allocating? GC is a fairly transverse cost, in that it can charge the good parts of your program for the expenses of the bad.

Guile uses the Boehm-Demers-Weiser conservative collector. For what it is, it's pretty good. However its stock configuration does not provide very much insight into the allocation patterns of your program. One approximation that can be made, though, is that the parts of the program that cause garbage collection to run are the parts that are allocating the most.

Based on this insight, Guile includes a statistical profiler that samples when the garbage collector runs. One thing to consider is that GC probably doesn't run very often, so for gcprof tests, one might need to run the test for longer. In this example, I increased the load to a million requests.

$ guile --no-debug
> (use-modules (statprof))
> (gcprof (lambda () (load "examples/web/hello.scm")))
%     cumulative   self             
time   seconds     seconds      name
 86.55     82.75     82.75  setvbuf
  9.37      8.96      8.96  accept
  1.70      1.63      1.63  call-with-error-handling
  1.31      1.25      1.25  %read-line
  0.29      0.28      0.28  substring
  0.24      0.23      0.23  string-downcase
  0.10     91.80      0.09  http-read
  0.10      0.09      0.09  parse-param-list
  0.10      0.09      0.09  write-response
---
Sample count: 2059
Total time: 95.611532937 seconds (9.371730448 seconds in GC)

Here we confirm the result that we saw in the low-level profile: that the setvbuf Scheme procedure, which can cause Guile to allocate buffers for ports, is the primary allocator in this test.

Another interesting question to answer is, "how much are we allocating, anyway?" Using the statistics REPL command, I can see that the 100K requests entailed a total allocation of about 1.35 GB, which divides out to 13.5 KB per request. That sounds reasonable: about 4 KB each for the read and write buffers, and some 4 KB of various other allocation: strings, pairs, the final bytevector for output, etc.

The test incurred 220 stop-the-world garbage collections. So, about 1 out of 450 (0.2%) of requests trigger a GC. The average GC time seems to be about 5 ms (1100 ms / 220 times). That squares fairly well with our last-percentile ApacheBench results.

The total heap size is modest: 14 megabytes. It does not leak memory, thankfully. If I run mem_usage.py on it, I get:

Mapped memory:
               Shared            Private
           Clean    Dirty    Clean    Dirty
    r-xp    1236        0     1028        0  -- Code
    rw-p      24        0       28      160  -- Data
    r--p      60        0     1580      112  -- Read-only data
    ---p       0        0        0        0
    r--s      24        0        0        0
   total    1344        0     2636      272
Anonymous memory:
               Shared            Private
           Clean    Dirty    Clean    Dirty
    r-xp       4        0        0        0
    rw-p       0        0        0    11652  -- Data (malloc, mmap)
    ---p       0        0        0        0
   total       4        0        0    11652
   ----------------------------------------
   total    1348        0     2636    11924

Native ahead-of-time compilation would allow for more shareable, read-only memory. Still, as it is, this seems acceptable.

a quick look at more dynamic tests

That's all well and good, you say, but it's a fairly static test, right?

For that I have a couple of data points. One is the simple SXML debugging test in examples/test/debug-sxml.scm, which simply spits back the headers that it receives, wrapped in an HTML table. The values are printed as the Scheme object that they parse to. Currently, I have a version of this script running on my site. (You can see the headers that Apache adds on, there.)

Testing it as before tells me that Guile can serve 6000 of these pages per second, on my laptop. That's pretty respectable for an entirely dynamic page that hasn't been optimized at all. You can search around the net for comparable tests in other languages; I think you'll find Guile's performance to be very good.

The other point to mention is Tekuti itself. Tekuti includes a caching layer in the application, so after the first request, it's not really a dynamic test. It does check to make sure its caches are fresh on every round, though, by checking the value of the refs/heads/master ref. But still, it is a test of pushing a lot of data; for my test, the page is 50 KB, and Guile still reaches 5700 requests per second on this one core, serving 280 megabytes per second of... well, of my blather, really. But it's a powerful blather-pipe!

related & future work

Here's a similarly flawed test from a year ago of static servers, serving small static files over localhost. Flawed, but it's a lot like this "hello world" test in semantics. We see that nginx gets up to about 20K requests per second, per core. It also does so with a flat memory profile, which is nice.

Guile's bundled web server is currently single-threaded and blocking, which does not make it a good frontend server. There's room for a project to build a proper web server on top of Guile, I think, but I probably won't do it myself. In the meantime though, I do want to offer the possibility for the built-in web server to be multithreaded, with some number of I/O threads and some more limited number of compute threads. I've been testing out some code in that direction -- in fact, this server is running that code -- but as yet Guile's synchronization primitives have too much overhead for it to be a real win. There's more runtime and compiler work to do here.

As far as web servers written in safe languages, it would be remiss to not mention Warp, a Haskell web server. Again, their tests effectively utilize multiple cores, but it seems that 20K per core is the standard.

Unlike Haskell, Guile lacks a proper event manager. I'm not sure whether to work on such a thing; Havoc seems to think it's necessary, and who am I to argue.

Finally, I mention a benchmark of python WSGI servers from a couple years ago. (Is March the month of benchmarks?) The python performance is notably worse; hopefully PyPy has improved things in the meantime. On the other hand, GEvent's use of greenlets is really nice, and makes me envious.

conclusions

Hey, you read the thing! Congratulations to you! Good thing you didn't just skip down to the end :)

If I have a message to send, it's this: that you should consider using Guile to be perfectly acceptable for implementing dynamic web applications with high performance requirements.

It's a modest point, I know. There are all kinds of trade-offs here, but hey, Guile is plucky and still a little bit shy, but would love it if you to ask it to the hack.

If it works for you, boast about it to your colleagues! And if it doesn't, let us know, over at the usual places (guile-user@gnu.org, and #guile on freenode). Happy hacking!

by Andy Wingo at March 08, 2012 10:44 PM

March 07, 2012

Simón Pena

Mahjong Solitaire for the Nokia N9

Get Mahjong from the Nokia Store

Last week, we got Mahjong Solitaire for N9 finally published.

This has been a great opportunity to use QML in my daily work at Igalia, instead of using it simply for the occasional hacking, such as Butaca or the XKCD reader.

So far, comments in the Nokia Store have been really positive -although some people seem to miss the classic theme from the Mahjongs available back in Maemo. But not only the comments are positive: the application is currently listed in the first position of the Top Free games!

Drop me a line (spena at igalia.com) if you find issues, you have suggestions or if you simply want to complain about the colors ;)

by Simón at March 07, 2012 08:26 AM

March 06, 2012

Andrés Gómez

Extending the life of your N8x0: Update for Automatic Skype Launcher

I’ve just released the 0.0.2 version of Applications Fullscreener and Automatic Skype Launcher.

As I was already commenting in my previous post Extending the life of your N8x0: Automatic Skype Launcher, just download them and install them in your N8x0 for making it become a good 24/7 Skype phone.

The most important change for Applications Fullscreener is:

  • I’ve added a helper to launch a certain application and send the fullscreen key event some time afterwards.
    This is specially useful for launching an application through the DSME watchdog daemon in Maemo4.x. Using this helper as a wrapper, the application will receive the fullscreen event some time after being launched while the watchdog keeps track of the helper. In this case, if either the helper or the application dies, both die and, hence, the DSME will relaunch them both.

You can, also, check the complete ChangeLog for Applications Fullscreener.

The most important changes for Automatic Skype Launcher are:

  • I’ve added a Control Panel plugin for setting several behaviors of the application: starting an init service, using a watchdog for keeping it alive, trying to fullscreen Skype after launching it as a service and the time at which the service will be restarted, if so.

Automatic Skype Launcher Control Panel plugin snapshot

  • I’ve added a Home Desktop applet for making it easier to launch manually Skype, not having to get into the applications menu.

Automatic Skype Launcher Home Desktop applet snapshot

  • The Automatic Skype Launcher service was not stopping when the N8x0 was turned off while charging. Now this is corrected.
  • In the previous version, I added a cron.daily script to restart Skype (and the service). Actually, the N8x0 doesn’t have a cron daemon, by default. This is now corrected through the usage of an alarm triggered by the alarmd daemon.

You can, also, check the complete ChangeLog for Automatic Skype Launcher.

That’s it. Comments and patches are welcomed!

by tanty at March 06, 2012 03:04 PM

March 03, 2012

Javier Morán Rúa

LibrePlan makes easier to know the project status

If you follow closely the LibrePlan project, you will know that we are working in the development of the features that will be included in the LibrePlan 1.3 version, that is estimated to be released next April (you can look into the roadmap  here).

Among the things included in the roadmap, we regarded as very interesting to work in making the tool more intelligent by providing a set of indicators informing about the status of the project. At present, of course, you can also know the status of a project examining the planning and extracting the reports existing in LibrePlan. However, we thought that we could go one step further.

We realized that although monitoring and controlling the project plan can be done by the project manager quite fast and easy, there is a user role, different from the project manager, that is also very interested in the status of the company projects. This user can be defined as an employee with a chief position in the organization hierarchy. For instance, the CEO of a company can be a good prototype of this sort of profile.

This profile has some characteristics that make him different from the project manager role:

  • The CEO is a user with less project management knowledge than the project manager and, therefore, has more difficulties in analyzing the project Gantt, in interpreting correctly the progress measurements or in applying project management techniques like the EVM (Earned Value Management) and the Monte Carlo simulation implemented in LibrePlan.
  • The CEO is a user whose main duties are not related with project management and, because of this, he has less time available to follow the day a day of the projects opened in the company.
  • Although the CEO has both less project management knowledge and less time to devote to it, he is interested in knowing how well or bad is going a project to make executive decisions if required.

So, taking into account the above points, we assessed that for this kind of chief employee could be very useful a set of metrics, usually called KPI (Key Performance Indicators). Project management KPIs measure how well a project is performing according to its goals and objectives, i.e., to finish on time and with the expected cost.

KPIs are perfect for the CEO users because they have three properties that satisfy the needs and use pattern of these executive users:

  1. They sum up information. They gather planning data and through calculations provide a panoramic view of the situation of a project according to the specific goal aspect they are are designed to measure.
  2. They are easy to understand. They do not require a lot of project management background to be read. Besides, in LibrePlan they can be merged to provide a single verdict about a project.
  3. They are fast. The user is not required to spend much time with the project plan to be able to get a view about the status of the project.

I would like also to highlight that, although they are very important for the chief employees, the KPIs are also very helpful for the project managers and all the people taking part in the planning because they save time and provide and a good picture of the status of the project at any moment.

The KPIs will be displayed in LibrePlan 1.3 in a screen of the project planning that will be called the dashboard. With this name we are drawing an analogy with physical dashboards present in complex machines like, for example, a plane where the pilots have a flying deck with a bunch of sensors monitoring any single aspect of the flight. In the same way, in the LibrePlan dashboard, the person in charge of the planning will be able to look at a set of numerical data and charts that will help him to bring the project to fruition.

We have been studying which KPIs to implement to launch the first version of the dashboard and the principles we have followed in the research have been two: to cover the relevant aspects of the status of a project and, second, to maximize the value added to the program.

Once concluded this investigation process, the result has been the identification of four dimensions and a set of KPIs per dimension. Besides, according to this four dimensions, we designed the layout of the dashboard divided in four areas, each one containing the KPIs belonging to it inside.

The dimensions and KPIs are the next ones:

Progress

This dimension measures which is the progress degree of the project, i.e, work already done versus work remaining to do to close the project. KPIs:

  • Global progress chart. It will sum up the current global progress of the project and will show the theoretical value the project progress should have if all things went as expected.
  • Task status chart. It will show the number of tasks finished, ready to start, blocked by a previous dependent task, etc..

Time

This area will show how well the project is performing in time according to deadlines and other time commitments. KPIs:

  • Task completion delay histogram. It will show an histogram chart with the number of days the tasks of the project are finishing ahead of time or after the planned end date.
  • Deadline violation KPI. Pie chart with the tasks which have not hit the deadline, the tasks which have hit it and the tasks without a configured one.
  • Margin with project deadline. Number of days the project finishes after or before the configured project deadline.

Resources

This dimension will do an analysis of the resources being allocated in the project. KPIs:

  • Estimation accuracy histogram. It will be an histogram with the deviation between the hours planned and the hours finally devoted by the company resources to the tasks of the project.
  • Overtime ratio. It will show how much overtime the resources allocated to the project are having.

Cost

This area will include some metrics belonging to the EVM technique. These metrics are function of time and in this area will be shown calculated at the current date. KPIs:

  • Cost Variance. It will be the difference between the BCWP (Budgeted Cost Work Performed) and the ACWP (Actual Cost Work Performed). It says how much we are losing or winning regarding to the estimated cost planned.
  • Cost Performance Index. It informs about the current rate of win/loss value per time unit.
  • Estimated as Completion (EAC). It is a projection that estimates which will be the final project cost at completion.
  • Varience at Completion. It is a projection of the estimated benefit or loss at completion time.

And finally, as a picture is worth a thousand words, although the dashboard is work in progress, I would like to include here a snapshot of some KPIs mentioned above that the LibrePlan team is implementing currently.

KPI snapshot

KPIs development (work in progress)

Besides, as we usually do, if you want to share with us your ideas or requests about what KPIs you miss or things that you regar as important for future, just let us know about it using the communication resources we have available in LibrePlan.

by javier moran rua at March 03, 2012 09:33 PM

February 28, 2012

Carlos García Campos

WebKitGTK+ 2.0 for GNOME 3.6?

That’s the plan! But, what’s exactly WebKitGTK+ 2.0? It will be the first stable release of WebKit2 GTK+ API, leaving the current WebKit GTK+ API in a maintenance mode. WebKit2 GTK+ is not just about multi-process architecture, robustness, stability and all other great things the new WebKit2 model brings, it’s also a redesign of the current WebKitGTK API to make it even more convenient and easier to use.

In the Igalia WebKit team,  we have planned a Roadmap of the tasks we will be actively working on to release WebKitGTK+ 2.0 for GNOME 3.6. Even though unit tests play a very important role in the WebKit2 GTK+ API development, we know that real applications using the API usually reveal issues that the unit tests or test programs like MiniBrowser don’t catch. For that reason, we have set milestones consisting of porting real applications to the new API.

  • GNOME 3.4: Applications using a small part of the API. We will focus on porting Devhelp.
  • GNOME 3.5: With the first unstable releases of the 3.5 cycle we should be able to port applications using the API more extensively. We will focus on porting Yelp.
  • GNOME 3.6: We should be able to port any application using WebKitGTK+ without major regressions. We will focus on porting Epiphany.

This is, of course, a plan, if we eventually don’t manage to achieve the milestones, we will release WebKitGTK+ 1.10 for GNOME 3.6 and current plan will be postponed to GNOME 3.8. Needless to say that any help would be more than welcome :-)

by carlos garcia campos at February 28, 2012 02:51 PM

February 26, 2012

Víctor Jáquez

Debian’s mutt with notmuch support

One of my weekend tasks was to reorganize my email environment. For reading email I use mutt, configured to grab the email from an IMAP server. For sending email, I have a minimal exim setup securely relaying to a smart host.

Mutt is a great email browser, but it is very bad at handling IMAP. Besides, I started to need searching through all my email. The solution for the first problem is offlineimap, a program wrote in Python, that “synchronizes emails between two repositories”. It downloads my email from the IMAP server into my laptop, so I work in my email locally, and if I delete an email locally, offlineimap will delete it in the next sync operation.

The solution for the second problem, the search, is notmuch, which is a email indexer, enabling fast searches among a vast mail collection. So, once new mail arrive (or is deleted) with offlineimap, notmuch (de)indexes it.

But another problem appear: how to query to notmch in an integrated way with my mail reader? One solution is provided by mutt-ks, a fork of mutt with notmuch support tightly integrated.

But I use Debian, and I like its package management. So I needed to craft a Debian package for mutt-kz.

I grabbed the Debian’s repository for mutt and re-based, one by one, the patches from mutt-kz.

The result is stored in this repository.

And now, I can query notmuch in mutt and immediately browse the result set.

by vjaquez at February 26, 2012 04:30 PM

February 24, 2012

Xabier Rodríguez Calvar

Mixed QML/C++ objects

One of the good things of QML is that you can have both C++ and QML code and interact between them. For example, from C++, you can access the QML tree and invoke methods, change properties, etc.

The other way around, you can also define C++ objects and interact with them from QML. Here you have two ways of doing it:

  • Instantiating from C++ and adding the objects to the QML context, meaning that you can invoke the public slots and access the properties.
  • Registering the QML type with qmlRegisterType and then instantiating it from QML.

At the Qt documentation you can find examples about how to implement the different approaches so I won’t talk too much about them and I’ll focus in a special case of the last approach.

Let’s see a QML code like this:

Item {
    id: myObject
    function doCoolStuff() {
        // doing really cool stuff here
    }
    Rectangle {
        anchors.fill: parent
        color: "red"
    }
}

Button {
    text: "Do cool stuff!"
    onClicked: myObject.doCoolStuff()
}

Imagine now that painting that rectangle is something that must be really done by your object, because it is needed and inherent to it, and so is the function. If the code is written only in QML, the answer is obvious, just move the whole Item code to a .qml file and leave the main code like this:

MyObject {
    id: myObject
}

Button {
    text: "Do cool stuff!"
    onClicked: myObject.doCoolStuff()
}

Let’s suppose that you need some C++ code in that object for whatever reason (you want to use some GNOME library, for instance). In this case you need to write it in C++ to define the public slots in that language. Our first step would be something like this:

#include <QtCore>
#include <QtDeclarative>

 class MyObject : public QDeclarativeItem
 {
     Q_OBJECT

// Define some Q_PROPERTY here with its methods

 public slots:
     void doCoolStuff(void);

// We could even define some signals
 };

For the slot, it does not matter if you declare it as slot or with Q_INVOKABLE because QML will see it both ways. Of course, don’t forget to write the cpp file with the implementation for the slot ;) . And you also need to declare the QML type, for example in your main.cpp file:

#include <QtDeclarative>
#include "myobject.h"

int main(int argc, char *argv[])
{
    // ...
    qmlRegisterType("myapp", 1, 0, "myobject");
    //...
}

So far it is not different from what you can read at Defining new QML elements section of the Qt doc.

But what about painting the rectangle? We can do it with Qt code, but as we are lazy bastards and want to use QML for that, we have two options. One of them is forgetting about it in the C++ code and having something ugly like:

import myapp.myobject 1.0

MyObject {
    Rectangle {
        anchors.fill: parent
        color: "red"
    }
}

But come on, that rectangle is part of the object and nobody should write the Rectangle themselves. So we can take the better approach of moving the Rectangle to a different MyObject.qml file and loading it in the constructor of the C++ class:

#define QML_PATH "/path/to/the/qml/files/"

MyObject::MyObject(QDeclarativeItem *parent = 0) : QDeclarativeItem(parent)
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(QML_PATH "MyObject.qml"));
    QDeclarativeItem *rect = dynamic_cast<QDeclarativeItem *>(component.create());
    rect->setParentItem(this);
}

Voilà.

by calvaris at February 24, 2012 07:16 PM

February 21, 2012

Andy Wingo

for love and $

Friends, I'm speaking at JSConf.us this year! Yee haw!

I would have mentioned this later, but events push me to say something now.

You see, I wrote the web server that runs this thing, together with the blog software. I've been hacking on it recently, too; more on that soon. But it seems that this is the first time I've noticed a link from a site that starts with a number. The URI parsers for the referer link were bombing out, because I left off a trailing $ on a regular expression.

So, for love and $, JSConf ho! We ride at dawn!

by Andy Wingo at February 21, 2012 04:48 PM

palindromically delimited carnival

Our time aligns on strange axes, sometimes. Last palindrome day, 11/11/11, found me walking the streets of Gothenburg with Werner Koch, the GPG maintainer. Werner said that in Germany, the carnival season opens on the 11th of November, at 11:11:11 in the morning. Today, 21022012, closes the carnival week here in Catalunya.

I was in Gothenburg for FSCONS. It so happens that the videos for the talk I gave there, Guile: Free Software Means of Production, just came out last week. So, as another point along that carnival axis, I offer in <video> form:

Click to watch

Alternately you can download the video directly (~112MB, 50 minutes). There are notes too, a superset of the slides from the talk.

As I said back then, this one was aimed at folks that didn't necessarily know very much about Guile. It was also different from other talks in that it emphasized Guile as a general programming environment, not as an extension language. Guile is both things, and as the general-purpose side gets a lot less publicity, I wanted to emphasize it in this talk.

In the last 20 minutes or so, we did a live-hack. Inspired by a tweet by mattmight, we built Bitter, a one-bit Twitter. I tried to convey what it's like to hack in Guile, with some success I think. Source code for the live-hack, such as it is, is linked to at the end of the page.

by Andy Wingo at February 21, 2012 12:07 PM

February 20, 2012

Adrián Pérez

Some Tracker + SPARQL bits

Those are some notes about Tracker with links and information which has been useful to me when using Tracker as data storage backend in a project. Maybe those will be useful to someone else out there :)

Reference documentation

The basics are the W3C standards:

Tracker-specific info

  • Tracker adds some extra features which can be used in SPARQL queries. Some of them can be used to make queries faster (see below).
  • It is possible to subscribe to notifications of changes to the Tracker database. However, using the low-level D-Bus support is crude, therefore it is better to use something like TrackerLiveQuery.

Optimizing queries

At some point one may realize that a particular query is not running fast enough, and usually the first thought would be to blame Tracker being slow: as a matter of fact Tracker tends to be quite fast, but sometimes the way it translates the SPARQL queries to SQL makes them be slower than they could be. And the good news is that most of the queries can be tweaked to facilitate the job of the query optimizer. There are some hints in the Tracker wiki:

Also, I would recommend reading those two nice articles by Adrien Bustany:

Undocumented behavior

Undocumented behavior exists in Tracker to a certain degree. Some of the undocumented behavior is caused by the fact that SQLite is used underneath and that the SPARQL parser included in Tracker is quite permissive and will just pass-through certain constructs when generating the SQL queries.

As an example, the regular expression syntax used y SPARQL does not include predefined character classes, but as SQLite uses POSIX regular expressions internally, the following filter expression works:

  SELECT ?name
  WHERE { ?urn nco:imNickname ?name
          FILTER (bound(?name) && !REGEX(?name, "[[:space:]]+")) }

(Obtains the nick names of instant messaging contacts which do not have spaces in them.)

Another example of undocumented behaviour is the fact that aggregate functions (e.g. COUNT) can be used on the result of a property function. For example, take this query:

  SELECT nie:url(?urn) COUNT(?regions)
  WHERE { ?urn rdf:type nmm:Photo .
          OPTIONAL { ?urn nfo:hasRegionOfInterest ?region } }
  GROUP BY ?urn

(Obtains the URLs of images and the number of associated regions of interest.)

The above query would run faster if it would be possible to get rid of the OPTIONAL clause, by using a property function, but when an attribute has multiple values, the property function returns the concatenation of the values separated by commas, so COUNT would be expected choke when applied to that… No! Actually, the following works as expected:

  SELECT nie:url(?urn) COUNT(nfo:hasRegionOfInterest(?urn))
  WHERE { ?urn rdf:type nmm:Photo }
  GROUP BY ?urn

(Obtains the URLs of images and the number of associated regions of interest — faster version.)

by aperez at February 20, 2012 04:32 PM

Javier Muñoz

Security lessons at MSWL 2012

This past weekend I ended my lessons on our Master Software Libre.

If you follow this blog you will know I usually write down the topics I teach along these lessons. It is always good thing getting feedback and getting in touch with persons reading these lines.

By the way, this year our Master runs its fifth edition. I am proud to watch how it is working and how old and new students, teachers, collaborators, community advisors and all our friends build this knowledge community daily.

Having a broad look I am able to find plenty of technologies, hacking, know-how and a lot of relevant stuff each year.

Although teaching people is always a huge responsibility, I like to start my lessons remembering IT security is a hot topic and, in essence, this domain talks about sensible and dangerous topics; so prudence and good sense are always the right way to follow here.

OK … so nowadays, what am I teaching in those lessons really? what am I covering under the topics of Physical Security, Cryptography, Networking and Security Networking? and, at the end, on what kind of practical laboratories and exercises are we working?

Well, bearing in mind I think IT security is a very complexed topic where different social, economic and technological forces converge I compiled all security stuff covered in this V edition. In summary, some of the syllabus’s drivers were the following:

On Physical Security:

  • Physical system security methodologies
  • Environmental design
  • Design and evaluation of physical protection systems

On Cryptography:

  • Cryptographic models
  • Cryptographic systems
  • Free/open software tooling
  • Integration and usual cases

On Networking:

  • Foundations
  • User and Kernel stack implementation
  • Administration and tooling
  • Typical configurations and trouble shooting

On Security Networking:

  • Network attacks and defense
  • Good practices, blueprints and security methodology
  • Network device security
  • Network architectures
  • Integrity and availability
  • Exploitation and responsible disclosure
  • Underground markets
  • Vulnerability management
  • Risk analysis and defense models
  • Advanced and strategic defense in organizations

Aligned with these points, I ran some new live-demos and attacks too.

Apart of the usual attacks showing design flaws, networking protocol weaknesses, practical communication hijacking or break-in techniques; we studied real networks following one ethical and legal approach. It was useful to identify their strengths and weaknesses while suggesting possible solutions and alternatives.

Finally, together with the design and model of their own embassy by students, we jumped to Linux kernel land to study (line by line in source code) as a real Linux kernel rootkit works under the hood; hiding network connections, users, files and so on.

I would like to think this new 5th promotion have now a better insight and perception of the real risk and magnitude of the battlefield out there … I think so :)

Happy hacking!

by javier at February 20, 2012 03:38 AM

February 16, 2012

Andy Wingo

unexpected concurrency

OK kids, quiz time. Spot the bugs in this Python class:

import os

class FD:
    _all_fds = set()

    def __init__(self, fd):
        self.fd = fd
        self._all_fds.add(fd)

    def close(self):
        if (self.fd):
            os.close(self.fd)
            self._all_fds.remove(self.fd)
            self.fd = None

    @classmethod
    def for_each_fd(self, proc):
        for fd in self._all_fds:
            proc(fd)

    def __del__(self):
        self.close()

The intention is pretty clear: you have a limited resource (file descriptors, in this case). You would like to make sure they get closed, no matter what happens in your program, so you wrap them in objects known to the garbage collector, and attach finalizers that close the descriptors. You have a for_each_fd procedure that should at least allow you to close all file descriptors, for example when your program is about to exec another program.

So, bugs?

* * *

Let's start with one: FD._all_fds can't sensibly be accessed from multiple threads at the same time. The file descriptors in the set are logically owned by particular pieces of code, and those pieces of code could be closing them while you're trying to for_each_fd on them.

Well, OK. Let's restrict the problem, then. Let's say there's only one thread. Next bug?

* * *

Another bug is that signals cause arbitrary code to run, at arbitrary points in your program. For example, if in the close method, you get a SIGINT after the os.close but before removing the file descriptor from the set, causing an exception to be thrown, you will be left with a closed descriptor in the set. If you swap the operations, you leak an fd. Neither situation is good.

The root cause of the problem here is that asynchronous signals introduce concurrency. Signal handlers are run in another logical thread of execution in your program -- even if they happen to share the same stack (as they do in CPython).

OK, let's mask out signals then. (This is starting to get ugly). What next?

* * *

What happens if, during for_each_fd, one of the FD objects becomes unreachable?

The Python language does not guarantee anything about when finalizers (__del__ methods) get called. (Indeed, it doesn't guarantee that they get called at all.) The CPython implementation will immediately finalize objects whose refcount equals zero. Running a finalizer on the method will mutate FD._all_fds, while it is being traversed, in this case.

The implications of this particular bug are either that CPython will throw an exception when it sees that the set was modified while iterating over it, or that the finalizer happens to close the fd being processed. Neither one of these cases are very nice, either.

This is the bug I wanted to get to with this article. Like asynchronous signals, finalizers introduce concurrency: even in languages with primitive threading models like Python.

Incidentally, this behavior of running finalizers from the main thread was an early bug in common Java implementations, 15 years ago. All JVM implementors have since fixed this, in the same way: running finalizers within a dedicated thread. This avoids the opportunity for deadlock, or for seeing inconsistent state. Guile will probably do this in 2.2.

For a more thorough discussion of this problem, Hans Boehm has published a number of papers on this topic. The 2002 Destructors, Finalizers, and Synchronization paper is a good one.

by Andy Wingo at February 16, 2012 10:12 PM

February 08, 2012

Claudio Saavedra

Wed 2012/Feb/08

February 08, 2012 09:35 PM

Diego Pino

Back from Fosdem

This was my first Fosdem and I have to say I enjoyed the experience a lot, despite the freezing cold in Brussels last weekend :) The amount and quality of the talks was overwhelming and there were many parties all along the event. I loved Fosdem atmosphere. Now I understand why so many igalians say Fosdem is one of the best events of year.

My main goal in this Fosdem was to give a talk about LibrePlan. The talk was held on Sunday morning and it was scheduled in the Lighting Talk track. I was happy to introduce LibrePlan to so many people and answer some questions that arose after the talk. Thanks everybody for coming. If you couldn’t attend Fosdem this year and would like to know more about LibrePlan, checkout the slides and video online (not available yet).

Apart from giving the LibrePlan talk, I also attended some other talks. Fosdem features many tracks with many interesting talks happening at the same. That makes it really difficult to arrange a solid agenda with all the talks you’d like to see. Fortunately some of the tracks were fully recorded, and talks will be available online soon.

The event started with the traditional welcome speech at Janson room. Actually, Fosdem started the day before with the also traditional get-all-together meeting at Delirium Tremens :)

After the welcome speech I moved to the room holding the Cloud track. The room was next to Mozilla’s room, which was also holding some talks I was interested in. I ended up spending more time at Mozilla’s room that at any other room. I especially liked the talk ‘Hacking Gecko‘ by Bobby Holley. It was a great introduction to Gecko and how to start hacking on Firefox. Bobby has a deep knowledge on the subject, but he was also very confident and shown a lot of attitude. It was together with Bdale Garbee’s keynote the best talk I attended at Fosdem.

At the Mozilla track I also attended:

  • Developing Firefox in 2012: Add-ons, Jetpack, Github and more by Dietrich Ayala. Also great talk although Ayala was a bit chilly. It was good to see Ayala in person, I still remember when I was a student about to graduate and I sent him an email with regard his NuSoap library, one of the first implementations of Soap for PHP.
  • Hack the web by Jeff Griffiths and Matteo Ferretti it was a nice introduction to JetPack, the new mechanism for developing extensions for Firefox.
  • Howto: Extensions for Thunderbird by Jonathan Protzenko, it was an introduction on how to develop extensions for Thunderbird, with real examples. Developing extensions for Thunderbird has always being harder than for Firefox as there is much less documentation. Fortunately, Jetpack will arrive soon to Thunderbird.
  • The State of Firefox Mobile by Lucas Rocha and Chris Lord, it was a good summary of the challenges to make Firefox mobile (Fennec) faster. The talks was particularly focused on Fennec for Android. It was a nice talk and very humble, I cannot think of many corporations which will openly acknowledge their products last up to 30 seconds to boot. I guess the first step to overcoming limitations is to admit them.
  • Boot to Gecko and Web API by Chris Jones and Andreas Gal. Boot to Gecko is an operating system based in open web technologies. The idea is to provide a single open platform where developers can build new applications, instead of targeting three different native mobile platforms (iPhone, Android and Windows). It definitively looks like the way to go and it is good Mozilla is pushing for it, but convincing developers to drop successful platforms with very proved successful business models is going to be hard. In any case, Boot to Gecko is still in its infancy.

On Sunday I gave my talk about LibrePlan and later I was talking with some people interested in LibrePlan. I also got the chance to talk with Apostolos Bessas from Transifex. Transifex is a localization platform that makes localization of applications very easy. We are using it now for LibrePlan and we love it. It was nice to meet you all.

Then in the afternoon I stuck to the Dev track and attended the following talks:

  • The Apache Cassandra storage engine by Silvain Brisbaine. It was a good talk but it got very much in detail in certain topics to my taste. I’d have preferred a broader and more introductory talk.
  • From Dev to Devops by Carlos Sánchez. Before the talk I was completely ignorant about the devops movement. Actually I was not thinking of attending but Carlos López, fellow igalian, sat next to me and convinced me to stay. I knew Carlos Sánchez from his work maintaining Maven and also because he studied at University of Coruña and is a friend of some Igalians. He gave an explanatory talk about what the devops movement is about. To put it in one line, devops is basically applying the principles of agile to system operations. Imaging using developing tools like Maven, Hudson, etc for system operations. The term is a combination of development + operations. After an introduction to the devops principles, he introduced Puppet, a declarative language for managing system operations.

Fosdem closed with a fascinating keynote by Bdale Garbee. Last year Fosdem brought a vision called FreedomBox. Everyday more and more of our lives is being uploaded online, while we trust our communications and data on third party applications. FreedomBox is about taking back the control of our own data and build federated networks that can communicate together knowing that our data won’t be compromised or abused by any corporation or public administration. Bdale Garbee gave a summary of all the progress made during last year in the FreedomBox project. It was good to see that a foundation has been set,  groups have been structured and things are rolling. However, there’s still much left to do. FreedomBox is a big challenge. I don’t know if it will be successful or even if it will ever be implemented one day, but I’m sure something will come out of FreedomBox. Progress and innovation happens when there are constraints and challenges to overcome, and the FreedomBox project is full of them.

Unfortunately due to the tight schedule I couldn’t attend to some of the talks by other Igalians. There were quite a few. API had a talk about the Status of accessibility on Gnome 3.4. Guillaume talked about Hacking in the real world, with a room fully packed of curious people. Mario and Philippe did a review of the latest progress and future roadmap of WebkitGTK+ at WebkitGTK+ status and roadmap to Webkit2. Xan López closed the Cross-desktop track with Web Applications in Gnome, featuring a live-demo of Angry Birds that really put the crowd in his pocket.

In summary, Fosdem was great. I’m looking forward to attending next year, with even more fellow igalians if possible. This year we were 14 in total, not bad. By the way, beer was terrific but I guess I don’t need to say it ;-)

by Diego Pino at February 08, 2012 02:59 PM

February 02, 2012

Felipe Erias

Going to FOSDEM 2012

Just a quick note to say that tomorrow I will travel to Brussels to attend FOSDEM 2012 with a bunch of colleagues from Igalia. Looking forward to it!

by femorandeira at February 02, 2012 09:01 AM

February 01, 2012

Andy Wingo

eval, that spectral hound

Friends, I am not a free man. Eval has been my companion of late, a hellhound on my hack-trail. I give you two instances.

the howl of the-environment, across the ages

As legend has it, in the olden days, Aubrey Jaffer, the duke of SCM, introduced low-level FEXPR-like macros into his Scheme implementation. These allowed users to capture the lexical environment:

(define the-environment
  (procedure->syntax
   (lambda (exp env)
     env)))

Tom Lord inherited this cursed bequest from Jaffer, when he established himself in the nearby earldom of Guile. It so affected him that he added local-eval to Guile, allowing the user to evaluate an expression within a captured local environment:

(define env (let ((x 10)) (the-environment)))
(local-eval 'x env)
=> 10
(local-eval '(set! x 42) env)
(local-eval 'x env)
=> 42

Since then, the tenants of the earldom of Guile have been haunted by this strange leakage of the state of the interpreter into the semantics of Guile.

When the Guile co-maintainer title devolved upon me, I had a plan to vanquish the hound: to compile Guile into fast bytecode. There would be no inefficient association-lists of bindings at run-time. Indeed, there would be no "environment object" to capture. I succeeded, and with Guile 2.0, local-eval, procedure->syntax and the-environment were no more.

But no. As Guile releases started to make it into distributions, and users started to update their code, there arose such a howling on the mailing lists as set my hair on end. The ghost of local-eval was calling: it would not be laid to rest.

I resisted fate, for as long as I could do so in good conscience. In the end, Guile hacker Mark Weaver led an expedition to the mailing list moor, and came back with a plan.

Mark's plan was to have the syntax expander recognize the-environment, and residualize a form that would capture the identities of all lexical bindings. Like this:

(let ((x 10)) (the-environment))
=>
(let ((x 10))
  (make-lexical-environment
   ;; Procedure to wrap captured environment around
   ;; an expression
   wrapper
   ;; Captured variables: only "x" in this case
   (list (capture x))))

I'm taking it a little slow because hey, this is some tricky macrology. Let's look at (capture x) first. How do you capture a variable? In Scheme, with a closure. Like this:

;; Capture a variable with a closure.
;;
(define-syntax-rule (capture var)
  (case-lambda
    ;; When called with no arguments, return the value
    ;; of VAR.
    (() var)
    ;; When called with one argument, set the VAR to the
    ;; new value.
    ((new-val) (set! var new-val))))

The trickier part is reinstating the environment, so that x in a local-eval'd expression results in the invocation of a closure. Identifier syntax to the rescue:

;; The wrapper from above: a procedure that wraps
;; an expression in a lexical environment containing x.
;;
(lambda (exp)
  #`(lambda (x*) ; x* is a fresh temporary var
      (let-syntax ((x (identifier-syntax
                        (_ (x*))
                        ((set! _ val) (x* val)))))
        #,exp)))

By now it's clear what local-eval does: it wraps an expression, using the wrapper procedure from the environment object, evaluates that expression, then calls the resulting procedure with the case-lambda closures that captured the lexical variable.

So it's a bit intricate and nasty in some places, but hey, it finally tames the ghostly hound with modern Scheme. We were able to build local-eval on top of Guile's procedural macros, once a couple of accessors were added to our expander to return the set of bound identifiers visible in an expression, and to query whether those bindings were regular lexicals, or macros, or pattern variables, or whatever.

"watson, your service revolver, please."

As that Guile discussion was winding down, I started to hear the howls from an unexpected quarter: JavaScript. You might have heard, perhaps, that JavaScript eval is crazy. Well, it is. But ES5 strict was meant to kill off its most egregious aspect, in which eval can introduce new local variables to a function.

Now I've been slowly hacking on implementing block-scoped let and const in JavaScriptCore, so that we can consider switching gnome-shell over to use JSC. Beyond standard ES5 supported in JSC, existing gnome-shell code uses let, const, destructuring binding, and modules, all of which are bound to be standardized in the upcoming ES6. So, off to the hack.

My initial approach was to produce a correct implementation, and then make it fast. But the JSC maintainers, inspired by the idea that "let is the new var", wanted to ensure that let was fast from the beginning, so that it doesn't get a bad name with developers. OK, fair enough!

Beyond that, though, it looks like TC39 folk are eager to get let and const into all parts of JavaScript, not just strict mode. Do you hear the hound? It rides again! Now we have to figure out how block scope interacts with non-strict eval. Awooooo!

Thankfully, there seems to be a developing consensus that eval("let x = 20") will not introduce a new block-scoped lexical. So, down boy. The hound is at bay, for now.

life with dogs

I'm making my peace with eval. Certainly in JavaScript it's quite a burden for an implementor, but the current ES6 drafts don't look like they're making the problem worse. And in Scheme, I'm very happy to provide the primitives needed so that local-eval can be implemented in terms of our existing machinery, without needing symbol tables at runtime. But if you are making a new language, as you value your life, don't go walking on the local-eval moors at night!

by Andy Wingo at February 01, 2012 03:33 PM

Mario Sánchez

Back to FOSDEM

So it seems I’m going to FOSDEM this year (yay!), together with a bunch of other Igalians who will be attending as well, coming from different places from across the globe (well, mainly from Europe this time).

I know some people will probably disagree with me on this, but for me FOSDEM is one of the greatest events of this kind, and so I’m quite happy to go there this time, specially after not being able to attend last year due to some unexpected (and unavoidable) personal matters.

Opposite to other occasions, this time I’ll be there not only as an attendant but also as an speaker, talking about WebKitGTK+, its status and the roadmap of the project towards WebKit2 (the split process model “flavour” of WebKit), together with my mate Philippe, on Sunday afternoon. Thus, for the first time ever, nobody will be able to accuse me of going there just because of the beer event, which wouldn’t be true anyway.

For the impatient ones, the talk will be mainly about reporting on the work done during the last months in “WebKitGTK+ land“, as well as on the stuff that is already planned for the upcoming releases. Good examples of those would be, for instance, the ongoing effort to add support for Accelerated Compositing, or just the new features related to WebKit2GTK+ such as, of course, the solution for enabling accessibility support there. Ah! And of course, we’ll try to run some demos there too… fingers crossed!

Besides, I’m of course looking forward to meeting some people I haven’t seen for a while now (haven’t attended to the latest Desktop Summit either, due to very good reasons too), so if you see me around and want to chat and/or meet for a while, just let me know. I must look shy, but it’s usually a matter of minutes (seconds?) for my shyness to go away…

So that’s it. Just a final line to say “thanks” to my company for fully sponsoring this thing.

See you in Brussels!

by msanchez at February 01, 2012 01:19 AM

January 31, 2012

Joaquim Rocha

(Hopefully) Going to FOSDEM 2012

Most of you might have heard about the sudden “death” of the airline Spanair. I had never known of an airline stopping its planes on the same day it announces it’s rupture.
Several colleagues of mine in Igalia were affected by the events and guess with whom some of us (mostly Igalians based at Coruña) were flying to Brussels? That’s right…
Fortunately yesterday we bought new flights and decided to try to get the reimbursement for the cancelled ones later.

This means that thanks to Igalia:

I'm going to FOSDEM, the Free and Open Source Software Developers' European Meeting

I had two presentations in each of the last two editions of FOSDEM but I didn’t really have something new to show in this year’s so I’m attending only as a participant which doesn’t make it less exciting for me.

I have already some arrangements planned, as in having a beer with some folks, and you’re invited too if you wanna talk about Igalia or the projects I’m involved in.

See you in Brussels.

by Joaquim Rocha at January 31, 2012 08:35 AM

January 30, 2012

Enrique Ocaña

From source code to ndk-build using autotools and androgenizer

This post explains how to compile C source code for Android using the Native Development Kit (NDK) by using autotools to set up the building infrastructure and using androgenizer to convert that autotools infrastructure into Android.mk files understood by the ndk-build tool. I’ll first review some autotools concepts very quickly trough examples and iterate over them.

Simple program

(Download the testapp.tgz example or browse it online)

We start from a simple helloworld program with its main() function that depends on a sayhello() function. We want to compile it using autotools in the simplest possible way.

To create an autotools template from scratch, follow the instructions of this presentation, which are abridged here:

  autoscan
  mv configure.scan configure.ac
  # Add this line below the AC_INIT line:
  # AM_INIT_AUTOMAKE
  nano configure.ac
  autoheader
  aclocal
  touch NEWS README AUTHORS ChangeLog
  automake --add-missing --copy
  autoconf

Makefile.am should contain:

  bin_PROGRAMS = testapp
  testapp_SOURCES = testapp.c

Then, to compile, just:

  ./configure
  make

The testapp.tgz file is an example of this. Look at the “autoall” script.

Library + program using libtool

(Download the testlib.tgz example or browse it online)

In this case we have to add a new libtool line to configure.ac, apart from the automake one, under the AC_INIT line:

  AM_INIT_AUTOMAKE
  AC_PROG_LIBTOOL

This is how Makefile.am should look like:

  lib_LTLIBRARIES = libtestlib.la
  libtestlib_la_HEADERS = testlib.h
  libtestlib_la_SOURCES = testlib.c
  libtestlib_ladir = $(includedir)
  libtestlib_la_LDFLAGS = -avoid-version

  bin_PROGRAMS = testapp
  testapp_SOURCES = testapp.c
  testapp_LDADD = .libs/libtestlib.so
  testappdir = $(includedir)

The LDFLAGS are the flags passed to libtool, and are documented here and here in the Autobook reference. In this case, the “-avoid-version” forces generation of libtestlib.so instead of libtestlib.so.0.0.0 (versioned libs aren’t supported in Android).

Look at the “autoall” script in the example for all the details. Now it’s fully automatic, so you don’t have to do the insertions by hand in configure.ac.

Androgenized lib + program

(Download the androgenized-testapp.tgz example or browse it online)

All the C code must reside in a directory called “jni”, inside the main directory of the Android project we want to create (in the androgenized-testapp example only the jni is included, technically the other ones aren’t needed):

androgenized-testapp
  src (Java source code)
  libs (compiled binary libs and executables)
  obj (intermediate object code for libs and exes)
  jni
    Application.mk (actually not mandatory)
    Android.mk (generated by androgenizer, drives the compilation when using NDK)
    Makefile.am
    testlib.c
    ...

A new target called Android.mk must be created in Makefile.am:

Android.mk: Makefile.am
        androgenizer -:PROJECT testlib 

        -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir)
        -:SHARED testlib
        -:SOURCES $(libtestlib_la_SOURCES)
        -:LDFLAGS $(libtestlib_la_LDFLAGS) 

        -:PROJECT testapp
        -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir)
        -:EXECUTABLE testapp
        -:LDFLAGS -ltestlib
        -:SOURCES $(testapp_SOURCES)
> $@

Androgenizer must be downloaded and installed somewhere in our PATH from here. It has a very brief parameter documentation, and the best way to understand it is by seeing usage examples, such as all the androgenizer lines added to the Makefile.am in the GStreamer project.

In the Android.mk target shown above two modules are going to be compiled: “testlib” and “testapp”. Each module is declared with a “-:PROJECT” parameter. The rest of the lines belong to the current project (current module) until a new one is declared. I’ve left a separation between projects to illustrate this.

Next line should always be a “-:REL_TOP” and “-:ABS_TOP”, as recommended in USAGE.txt. These two values are used to check all the paths in LDFLAGS, CFLAGS, etc. and substitute local paths with absolute paths. This is important, because normal makefiles usually assume that the rules are executed from the subdirectory the makefile is in, while what is considered as the working directory for Android.mk makefiles is always the directory from which ndk-build is invoked. As you can imagine, compiler directives such as “-I..” are going to have a very different meaning and cause the wrong behaviour when passed to the compiler by ndk-build.

After that, we indicate the type of target for the project (“-:STATIC” for libtestlib.a, “-:SHARED” for libtestlib.so, and “-:EXECUTABLE” for testapp). The extension of the library/app is automatically calculated.

The “-:SOURCES” parameter is used to indicate the files to be compiled. In this case we can use the list of files already calculated by the previous automake rules (see testlib.tgz and testapp.tgz examples) and stored in the “libtestlib_la_SOURCES” variable.

The “-:LDFLAGS” parameter is used to generate the needed library dependencies for the current module. In the case of testlib, those dependencies are already calculated by automake in the “libtestlib_la_LDFLAGS”. In the case of testapp, it depends on testlib, so we indicate it manually with “-ltestlib”. That will translate into this line in the generated Android.mk file:

  LOCAL_SHARED_LIBRARIES:=libtestlib

this will make the NDK build scripts to link against the proper “libtestlib.so” (if the lib was dynamic) or “libtestlib.a” (if it was static). The NDK already knows how testlib was built and how it has to be linked.

The final “> $@” line just means that make has to take the output of the androgenizer command and dump it to a file named just like the target it’s being build, that is, “Android.mk”.

After all the autoscan, configure.ac customization, autoheader, aclocal, libtoolize, automake and autoconf steps we can “./configure” and “make Android.mk” to generate the “Android.mk” file. Note that no full “make” is needed. Then we step back one directory (“cd ..” to the project root) and perform the actual build using NDK (which has to be downloaded from here, installed and be in our PATH):

  ndk-build V=1

The V=1 option just prints out all the executed commands, which is very handy. The compilation result will be placed in the “libs” directory.

To understand the process a bit more, it’s a good idea to look into the generated Android.mk file:

  LOCAL_PATH:=$(call my-dir)
  include $(CLEAR_VARS)

  LOCAL_MODULE:=testlib
  LOCAL_SRC_FILES :=
          testlib.c
  LOCAL_LDFLAGS:=
          -avoid-version
  LOCAL_PRELINK_MODULE := false
  include $(BUILD_SHARED_LIBRARY)
  include $(CLEAR_VARS)

  LOCAL_MODULE:=testapp
  LOCAL_SRC_FILES :=
          testapp.c
  LOCAL_SHARED_LIBRARIES:=
          libtestlib
  LOCAL_PRELINK_MODULE := false
  include $(BUILD_EXECUTABLE)

Apart from some boilerplate (LOCAL_PATH, CLEAR_VARS, LOCAL_PRELINK_MODULE), we can distinguish the two modules (LOCAL_MODULE), its source files (LOCAL_SRC_FILES), inherited LDFLAGS (LOCAL_LDFLAGS), required libs (LOCAL_SHARED_LIBRARIES) and finally, the building instruction (BUILD_SHARED_LIBRARY, BUILD_EXECUTABLE).

Seeing the Application.mk and Android.mk supported directives are documented somewhere in your installation of the NDK. They support more options than the ones explained here. With this basic introductions, that documentation should be more understandable. Application.mk can be edited directly. Android.mk has to be customized using the “-:PASSTHROUGH” androgenizer parameters in Makefile.am. For example:

  -:PASSTHROUGH LOCAL_ARM_MODE:=arm

Unfortunately, real life autotools build scripts are a bit more complex than the examples shown here. Here are some debug tips that can be helpful:

  • Use “ndk-build V=1″ to get the exact command line used to compile each file. When something fails, execute that command line independently and examine all the flags passed to it trying to look for incorrect compiler flags or missing include paths. Try to figure out what the correct command line flags would be.
  • Locate where the offending flags come from in the Android.mk. From there, locate them in the Androgenizer Makefile.am target. Usually some Makefile.am variable has the wrong values. Need to debug more on how Androgenizer is called? Go to the desired directory, delete Android.mk, make Android.mk and see the executed command line.
  • Where the Makefile.am variables comes from? What Makefile.am variables should be used? Examine the generated Makefile to find the values of all possible Makefile.am variables. That’s the place to look to decide what to pass to Androgenizer and what not.

by admin at January 30, 2012 05:05 PM

Adrián Pérez

Recipe: Synchronize music folder to an external device

This is easy to come up with, but as I end up having to dig through rsync‘s manual page to find the relevant options to copy my music to a device that has a non-Unix filesystem, it may be good to just write the recipe down here. Note that I am assuming that the file system in the device does not permission bits and ownerships (e.g. FAT), so those are not to be kept, and using rsync --archive is not a good option rsync will fail to set those extra attributes.

rsync --progress --delete -vrtxmhi ~/Music/ /media/${target_device}/Music/

This is what I use to keep my music library synchronized across my laptop, my phones and the extra backup in an external hard drive :-)

by aperez at January 30, 2012 04:44 PM

January 29, 2012

Adrián Pérez

FOSDEM 2012

This year I will be attending FOSDEM for the second time, and I am really looking forward to it. Not only because my flight from Helsinki this year will allow me to arrive on time for the beer event, but because it is a great event that fosters the Libre Software / Open Source community, it is packed with loads of interesting talks and people have the possibility to get in direct touch with each other in good atmosphere.

Once again, I am glad to be part of an über-cool company like Igalia, which is sponsoring my trip to Brussels. See you all there!

by aperez at January 29, 2012 06:47 PM

January 28, 2012

Diego Pino

Beatiful PHP Code

Recently Salvatore Sanfilippo, creator of Redis, made the following controversial tweet:

“I’ve the feeling that Ruby, Python, and other communities should help the PHP community to reach a more viable language ASAP”. [link]

This is the kind of stuff which usually ignites a flame :) Fortunately the conversation evolved into a more healthy discussion about what PHP lacks, especially compared to Ruby. In any case, some times I feel the same as Salvatore, not much about the particularities of the language itself but how most people use it.

Compared to other languages, PHP is a low-entry language. It’s easy to pick up, even without much experience in programming. This brings good and bad stuff. People without much computer knowledge can implement their own ideas, which is good, but most part of the times without caring much about code quality. It’s very common to look for some PHP code and find stuff like building a very long HTML string and then echo it, for instance. Actually, it took me some years to learn that PHP can be used either as a template language and as a programming language. Once I learned this, I started to separate view code from business logic code in a much clearer and organized way, something which frameworks like Ruby on Rails foster and care about since day 1.

Code like this:

function list(array) {
   $html .= '<ul>';
   foreach ($array as $elem) {
  	$html .= '<li>'.$elem.'</li>';
   }
   echo $html;
}
</ul>

Could be rewritten as:

< ? function list(array) { ?>
   <ul>
   < ? foreach ($array as $elem) { ?>
      <li>< ?= $elem; ?></li>
   < ? } ?>
< ? } ?>
</ul>

Or even like:

function list($array) {
   include_once('templates/ulist.html.php');
}

(templates/ulist.html.php)

<ul>
< ? foreach ($array as $elem) { ?>
   <li>< ?= $elem; ?></li>
< ? } ?>
</ul>

Separating view from business logic makes code easier to read and understand. It also helps to start thinking more in an object-oriented way, encapsulating business logic in classes.

Take a look at this piece of real code. It’s part of the extension Kickstarter from Typo3 CMS.

(typo3conf/ext/kickstarter/class.tx_kickstarter_wizard.php)

$content = '
   <script language="javascript" type="text/javascript">
   function setFormAnchorPoint(anchor) {
      document.'.$this->varPrefix.'_wizard.action = unescape("'.rawurlencode($this->linkThisCmd()).'")+"#"+anchor;
   }
  </script>
';

Wouldn’t be easier to isolate the Javascript code into a different file and include it? This is what RoR does all time, it’s called partials. The same code in Rails would be something like this:

render 'partials/_jscode.html.eml', :varPrefix => @varPrefix, 
   :url => rawurlencode(self.linkThisCmd());

The snippet above could be translated into PHP as this:

Partial::render('partials/_jscode.html.php', array(
   'varPrefix' => $this->varPrefix ,
   'url' => rawurlencode($this->linkThisCmd()),
));

And write _jscode.html.php as:

<script language="javascript" type="text/javascript">
   function setFormAnchorPoint(anchor) {
     document.< ?= $varPrefix; ?>_wizard.action = unescape("< ?= $url; ?>") +
        "#"+anchor;
   }
</script>

Partial is a helper class which includes a file and make the hash of vars parameter visible inside the included file (check the code here: Partials-PHP). It also provides a function called inline which does the same as the method render but returns the result as a string. The original Typo3 code could be finally rewritten as:

$content = Partial::inline('partials/_jscode.html.php', array(
   'varPrefix' => $this->varPrefix,
   'url' => rawurlencode($this->linkThisCmd()),
));

This is just an example on how you can do your PHP code more beautiful and easier to understand. It’s not only a matter of whether PHP is a good or bad language itself (as any other language it has its pros and its cons), but also about how we as programmers use the language. Fortunately, nowadays in PHP there are good frameworks which promote good practises, frameworks like CakePHP, CodeIgniter or Kohana, which interestingly were inspired by Django and Rails.

by Diego Pino at January 28, 2012 10:01 PM

January 27, 2012

Mario Sánchez

Accessibility support in WebKit2GTK+

As Piñeiro already mentioned in some posts, last week a bunch of hackers attended the ATK/AT-SPI Hackfest 2012 here at the Igalia offices, in the lovely city of Coruña.

As the guy working on accessibility support for WebKitGTK+, I attended the hackfest to join some other great people representing different projects, such as Mozilla, Orca, AT-SPI, ATK, GTK+ and Qt. So, apart from helping with some “local” organizational details of the hackfest and taking some pictures, I spent some time hacking in WebKitGTK+‘s accessibility code and participating in some discussions.

And from that dedication I managed to achieve some interesting things too, being my favorite ones a big refactoring of the a11y code in WebCore (so it’s now better organized and hence more readable and easy to hack on) and pushing my patch for enabling accessibility support in WebKit2GTK+, after going through a meticulous process of review (see the related WK bug), which started with the patch I wrote and attached back when attending to the WebKitGTK+ hackfest, as I mentioned in my previous entry in this blog.

Yeah, I know that some weeks have already passed since then and so perhaps you’re thinking this could have been done faster… but I’ve spent some weeks on holidays in Barcelona in December (pictures here!) and so I wouldn’t have much time before January to devote to this task. However, the patch got integrated faster than what I would expect when I proposed the first version of it, so I’m quite satisfied and happy anyway just by being able to announce this at this moment. Hope you share my joy :-)

So, what does this mean from the point of view of accessibility in GNOME? Well, that’s an easy question to answer: from now on, every browser that uses WebKit2GTK+ will be as much accessible as those using the previous version of WebKitGTK+, and this is definitely a good thing. Of course, I’m certain there will be bugs in this specific part that will need fixing (as it always happens), but for the time being this achievement means “yet another thing less” preventing us from pushing for upgrading some applications to switch to WebKit2GTK+, such as devhelp (some ongoing work already done, as my mate Carlos announced yesterday), yelpliferea… and the mighty Epiphany browser, which is rocking more and more ech day that goes by.

Last, I’d like to share with you an screenshot showing this new stuff, but as I am a little bit tired of always using Minibrowser (that small browser we use for testing WebKit2), so I decided to try instead that new branch Carlos recently pushed for devhelp, so you could check that what I mentioned before is actually true.

So here you have it (along with a couple of additions done with Gimp):

As you can see, devhelp is running and Accerciser is showing the full hierarchy of accessible objects associated to the application, starting in the UI process (GTK+ world) and continuing in the Web process, where all the accessible objects from the WebKitGTK+ world are being exposed. As I explained in a previous post, the magic making possible the connection between the two process is done by means of the AtkSocket and the AtkPlug classes, also represented in the screenshot attached above.

So, that’s it.

by msanchez at January 27, 2012 02:06 PM

January 26, 2012

Carlos García Campos

Porting devhelp to WebKit2

When MiniBrowser was ported to the new WebKit2 GTK+ API, I said we had plans to create a webkit2 branch for epiphany. And we’ll do it as soon as we have enough API, but epiphany uses most of the WebKit API so this is going to take a bit. In the meantime, we have decided to focus on other applications that use a small part of the WebKit API like devhelp, yelp, liferea, etc. Yesterday I pushed a webkit2 branch into the devhelp git repository with some initial commits that allow to use devhelp with WebKit2. Even though WebKit2 is available in the latest WebKit unstable releases, there’s a bug and public headers are not installed, so you need to build WebKit from git to be able to build the devhelp webkit2 branch. The main functionality works, but there are still some features missing that we are currently working on:

  • Policy client: used by devhelp to decide what to do with unknown content and to open links in a new tab with middle click. Martin Robinson is working on Policy Client API for WebKit2, the patches are pretty good and will be pushed soon.
  • Search: We already agreed on the new API and Sergio Villar wrote the patch that will also land soon.
  • Printing: This is not only about adding API, it requires adding support for printing in the Web process too. The main problem is that we need to show the print dialog in the UI process and render pages for printing in the Web process, so we can’t use GtkPrintOperation. We have already patches to implement basic printing support and adding initial API. These patches only work for UNIX, so patches to make it work in win32 would be really appreciated.
  • Editing commands: There’s already a patch to add cut, copy and paste API, but we are discussing the possibility to move to a more generic approach for editing commands.

And here is the mandatory screenshot, although there’s nothing special since WebKit2 changes don’t affect the UI.

Devhelp using WebKit2

Devhelp using WebKit2

We will keep updating the webkit2 branch when new API lands in WebKit until there aren’t regressions. Then we’ll focus on yelp which requires two important challenges: DOM bindings and context menu API.

by carlos garcia campos at January 26, 2012 02:10 PM

January 24, 2012

Alejandro Piñeiro

ATK/AT-SPI2 Hackfest 2012: Days 2,3,4,5

Well, as in the previous hackfest, I planned to make a post per day, but in the end I didn’t. Next time I will not make any plan.

Yesterday we had our last day of the hackfest. It was, in my opinion, a productive Hackfest where each one had the opportunity to work with other people working in the same field, and discuss several topics regarding the current situation. If you want to know all of the details and conclusions, you could read a minutes-like brainstorming document on the wiki. But If you were to ask me to pick just one, I would mention the discussion about enabling the accessibility support by default. The main conclusion was stop to use the atk-bridge as a module, and instead have that feature integrated. Doing that has several advantages, including having it compiled (and thus tested) when someone compiles GTK+ or any GTK+ app, and not only when you want to compile the “accessibility stuff”. The implementation details are still not clear. Convert atk-bridge to a library and add a dependency on GTK+ and others? Integrate it in ATK (making the bridge something like the DBUS backend)? Integrate it in GTK+? Forget ATK, and let GTK+ talk directly with the accessibility tools using GDBUS (an option that I feel is too drastic or non practical, but still in the mind of Benjamin)? Now is the time to debate it, in order to have something decided by 3.4, which we can start to testing properly at the beginning of the 3.6 cycle. Interesting times these days.

As in the previous hackfest, other conclusion is that there is a lot of work to do, but not a lot of people to do it. And this was reflected by the amount of people in attendance (some photos here). Anyway, although we were not a lot of people, we had a lot of different backgrounds represented at the hackfest. People from GTK+, ATK, AT-SPI2, WebkitGTK, Mozilla, assistive tools and QT. For example, in several discussions Frederik Gladhorn explained how the qt-bridge implements certain features, in some cases in an different way than how atk-bridge does the same thing, as Mike noted recently on his blog.

Finally, I want to thank everyone who came to this hackfest, as they made this hackfest possible. I also want to thank Igalia, GNOME Foundation and Mozilla Foundation for their sponsorship.

by API at January 24, 2012 12:41 AM