Showing posts with label gnome. Show all posts
Showing posts with label gnome. Show all posts

Sunday, April 9, 2017

GMime 2.99.0 released

After a long hiatus, I am pleased to announce the release of GMime 2.99.0!

See below for a list of new features and bug fixes.


About GMime

GMime is a C library which may be used for the creation and parsing of messages using the Multipurpose Internet Mail Extension (MIME), as defined by numerous IETF specifications.

GMime features an extremely robust high-performance parser designed to be able to preserve byte-for-byte information allowing developers to re-seralize the parsed messages back to a stream exactly as the parser found them. It also features integrated GnuPG and S/MIME v3.2 support.

Built on top of GObject (the object system used by the GNOME desktop), many developers should find its API design and memory management very familiar.


Noteworthy changes in version 2.99.0

  • Overhauled the GnuPG support to use GPGME under the hood rather than a custom wrapper.
  • Added S/MIME support, also thanks to GPGME.
  • Added International Domain Name support via GNU's libidn.
  • Improved the GMimeMessage APIs for accessing the common address headers. They now all return an InternetAddressList.
  • g_mime_init() no longer takes any flag arguments and the g_mime_set_user_charsets() API has also been dropped. Instead, GMimeParserOptions and GMimeFormatOptions have taken the place of these APIs to allow customization of various parser and formatting options in a much cleaner way. To facilitate this, many parsing functions and formatting functions have changed to now take these options arguments.
  • InternetAddress now has a 'charset' property that can be set to override GMime's auto-detection of the best charset to use when encoding names.
  • GMimeHeaderIter has been dropped in favor of a much simpler index-based API on GMimeHeaderList.
  • GMimeHeaderList no longer caches the raw message/mime headers in a stream. Instead, each GMimeHeader now has its own cache. This means that changing the GMimeHeaderList or any of its GMimeHeaders no longer invalidates the entire cache.
  • GMimeParser has been fixed to preserve (munged or otherwise) From-lines that sometimes appear at the start of the content of message/rfc822 parts.
  • GMimeParser now also scans for encapsulated PGP blocks within MIME parts as it is parsing them and sets a flag on each GMimePart that contains one of these blocks.
  • GMimePart now has APIs for dealing with said encapsulated PGP blocks.

Developers interested in migrating to the upcoming GMime 3.0 API (of which GMime 2.99.0 is a preview) should take a look at the PORTING document included with the source code as it contains a fairly comprehensive list of the API changes that they will need to be aware of.


Getting the Source Code

You can download official public release tarballs of GMime at https://download.gnome.org/sources/gmime/ or ftp://ftp.gnome.org/pub/GNOME/sources/gmime/.

If you would like to contribute to the GMime project, it is recommended that you grab the source code from the official GitHub repository at https://github.com/jstedfast/gmime. Cloning this repository can be done using the following command:

git clone https://github.com/jstedfast/gmime.git

Documentation

API reference documentation can be found at https://developer.gnome.org/gmime/2.99/.

Documentation for getting started can be found in the README.md.

Sunday, August 14, 2011

GMime 2.5.10: A Call For Testers

I've just released GMime 2.5.10 which I hope to be the last of the 2.5 releases before I release 2.6.0. I feel that I've stretched the development of 2.6.0 out for far too long (2.5 development began at the end of April, 2009) and even though I didn't get around to doing everything I had hoped to do, I feel that the latest 2.5.x releases are such an improvement over 2.4.x that I just want to get it out there for developers to start using. But before I make a 2.6.0 release, I'm hoping to get some feedback and some testing.

What's new?

New for the release of 2.5.10 is GMimePartIter which replaces the need for g_mime_object_foreach()and its awkward callback requirement, instead allowing you to take the far nicer iterator approach that is popular in the C# and Java worlds (known as IEnumerator in C#). This new iterator, like the foreach function it replaces, iterates over the MIME tree structure in depth-first order.

Inspired by IMAP's FETCH body part-specifier syntax, I've implemented a method allowing you to jump to a part based on a part-specifier string (aka a path): g_mime_part_iter_jump_to(). Also implemented is a function called g_mime_part_iter_get_path(), which can be used to tell you the current part-specifier path of the iterator.

For example, if you had the following MIME message structure:

multipart/related
  multipart/alternative
    text/plain
    text/html
  image/jpeg

The body part-specifier paths would be:

1    multipart/alternative
1.1  text/plain
1.2  text/html
2    image/jpeg

This means that g_mime_part_iter_jump_to(iter, "1.2") would jump to the part specified by the path "1.2" which, as we can see above, would be the text/html part. Calling g_mime_part_iter_next(iter) would iterate to the next part, being the image/jpeg, while calling g_mime_part_iter_prev(iter) would iterate backwards to the text/plain part and calling it again would iterate backwards to the multipart/alternative.

What I Need From Testers

My feeling is that developers will want to use this cool new body part-specifier path functionality for aiding them in implementing IMAP servers and/or clients. Because of this, it would be great if GMime's implementation matched IMAP's specification exactly. The problem is that I don't have the time or energy to verify that the paths work out to be identical in all cases. So... if you are one of those developers who is interested in using this functionality and need it to be identical to IMAP's syntax (or would really like it to be), I'm hoping that you could test it out and make sure that it matches. Especially worthwhile of testing, I'd imagine, is having message/rfc822 parts in the tree. I suspect that, if anywhere, this is where differences may be.

If body part-specifier paths aren't something you care about, don't fret; the rest of the iterator API needs testing as well and if you have no interest in the iterator API at all, perhaps you'd be willing to test the S/MIME functionality (especially since I haven't figured out how to test it myself, given that I don't have an S/MIME cert nor have I figured out how to generate one or add one to my gpgsm keyring).

Your help will be greatly appreciated.

Thursday, July 29, 2010

Re: Red Hat, 16%. Canonical, 1%.

While some people are busy complaining that Canonical doesn't contribute as much as others, I'd like for everyone to take a step back and ask themselves, "what would Gunny say?"

I'll tell you what he'd say. He'd say,

Hmm, that's interesting. Do you know what makes me sad? YOU DO! Maybe we should chug on over to mamby-pamby land where maybe we can find some self-confidence for you, you jack-wagon! Want a tissue?

After he finished ripping someone a new one, he'd point out that in that very same GNOME Census slide deck, I am ranked #8 in the top contributors list and I haven't contributed much of anything to any of the core GNOME components in about 5 years.

Yeah, that's right you cry babies, I put all y'all to shame.

On a more serious note, for better or worse, we all knew what we were getting into when we decided to take up the Free Software baton and start running with it. This is just how Free Software works. Don't like it? Cry me a river.

tl;dr

Update: It seems my post here has been misinterpreted. Allow me to try and rectify this. I'm not pissed off at Greg for voicing his opinion. We all do it. I'm just making a mockery of the whole situation because I was itching to trollcat and because I wanted to pat myself on the back for being #8 on the individual contributors list in terms of commits (as meaningless as that is). Also because I was up late last night and saw that Geico commercial with R. Lee Ermey which just cracks me up every time I see it.

Saturday, May 22, 2010

Reflecting on 10 Years at Ximian


IMG_1047, originally uploaded by jstedfast.

Today marks my 10th anniversary since I was hired at Helix Code to work on Evolution.

In that time I've gotten to work closely with and learn from some of the most talented developers in the Free Software community including Michael Zucchi, Miguel de Icaza, Federico Mena-Quintero, Chris Toshok, Larry Ewing, Michael Meeks, Dan Winship, Radek Doulik, Joe Shaw, Vlad Vukićević, Dave Camp, Dan Mills, and many others (too many to name!).

Back in the early days of Helix Code/Ximian, we all worked tirelessly to put together the very best GNOME distribution we could and make Evolution the very best groupware client we could.

We had big dreams and I like to think we succeeded. GNOME has become mainstream and the Linux Desktop can most definitely be measured as a success.

Of course, we couldn't have done it without all the help and hard work from the entire GNOME community.

Today, a younger generation of hackers are taking up the reigns to make GNOME awesome with things like the Paper Cuts project by David Siegel's team at Canonical and the work being done by Red Hat on the new GNOME-Shell.

I'm still working with a couple of my old Evolution teammates like Larry Ewing and Chris Toshok on the Moonlight project in the hopes of making it possible for Linux Desktop users to view Silverlight content on the web. We've been making great progress with implementing Silverlight 3.0 and 4.0 features in svn and I've got some accomplishments on that front that I should really blog about but I've just been so busy.

Much love to all you GNOMEies and thanks for all the support and love over the past decade!

Monday, October 19, 2009

Looking Back: 10 Years of Ximian

Nat and Miguel both reflected on the incorporation of Ximian which has made me a bit nostalgic myself. I've only been with Ximian for about 9 and a half years, but they have been pretty awesome years! I'm very thankful for having had the chance to be a part of something great and for having been able to work with both Nat and Miguel, 2 of my heroes.

The things I respect most about both Nat and Miguel are their positive attitudes and energy. They both have an amazing ability to inspire the people around them to do great things, and we did. From Ximian Desktop and Evolution to Mono, Moonlight and SuSE Studio. Nat and Miguel have set out to change the Linux Desktop for the better, and I believe they (and we, together with the rest of the GNOME and Mono communities) have accomplished that. So congratulations Nat & Miguel on 10 years of Awesome(tm)!

Saturday, July 11, 2009

Re: Let's All Say It Together.

I wasn't at the Gran Canaria Desktop Summit 2009, so I'm learning about this second hand from people like David Schlesinger, Natin Yellin and a number of people I know personally who attended the conference. It is important for us to respect all of our peers no matter their skin color, their religion or other beliefs, their gender, or any other factor. And that goes for respecting people outside of our community as well.

Because of this, I am casting my vote:

STOP sexism by Casey West. License:
"I want the [...] open source [...] communities [I participate in] to be a dignified, respectful, inclusive, and welcoming place. … We’ve all been witnesses to off-color jokes, misogynistic back channel chatter, questionable imagery and unnecessary, trolling comments. I pledge to do better to stand up and call this behavior out when I see it in conferences, online and other public settings. I don’t expect it to go away but I’m not going to tacitly condone it any longer."


(From Nick via Luis via David)
Update: As Natan Yellin has commented below, he was not actually at the conference - it was my mistake in thinking he was.

Sunday, February 8, 2009

Alleyoop 0.9.4 released

It's been ages since the last release of Alleyoop, but an update has finally arrived. I've just fixed up Alleyoop to build on openSUSE 11.1 (some libbfd stuff has changed, apparently) and so I've dropped the need for libbfd and libiberty completely. The code that used those libraries didn't really gain us any extra information that Valgrind wasn't already giving us anyway, so it as rather pointless.

It looks like a year and a half or so ago I fixed some parser bugs too and just never made a new release with those fixes.

So now Freedom Lovers who prefer a GUI can once again Valgrind their applications 'til their heart is content.

You can download the new Alleyoop 0.9.4 package here.

Oh, also, if there are any bored web developers out there, I'd appreciate it if someone could make a less-ugly website than what is currently at http://alleyoop.sourceforge.net. In case you couldn't tell, I'm horrible at website design.

As another fabulous example of my webdesign prowess, take a gander at GMime's website. So yea, that site could also use a make-over.

Update: Thanks to Akos Kemives for his improved website design for Alleyoop!

Sunday, October 5, 2008

Parallel-Installable Gtk-Docs

I recently release GMime 2.4.0 but missed the fact that the gtk-docs would install into the same location as the old 2.2 docs, namely ${prefix}/share/gtk-doc/html/gmime. Thwe problem is clear, since GMime 2.4 changed API (rather than just extending the 2.0/2.2 API), GMime 2.4 really needs to be fully parallel installable.

Thanks to Gilles Dartiguelongue from the Gentoo community for discovering this and bringing it to my attention.

As I tried to figure out how to accomplish what I needed, I discovered that Gtk-Doc needed some fixes so I did a quick hack and submitted it upstream.

Unfortunately, my original fix was broken in that I didn't realize that a simple version extension to the install directory wouldn't be enough because GNOME's devhelp program expected the .devhelp and .devhelp2 files would be named with the same version extension, or they would not be detected.

After that was pointed out to me, I looked deeper into the problem and discovered it wasn't such a terribly hard fix afterall, just a little shell scripting magic was all that was needed ;-)

Since Stefan Kost (the gtk-doc maintainer) and myself were both interested in such a solution, I figured there must be other library maintainers who would be interested in this and so thought I would blog about it.

For those interested in packaging GMime 2.4.x for the various distros, I'll be releasing a 2.4.2 release in the next day or so (going to wait a little longer just in case anyone finds any other last minute parallel-install bugs in the gmime-2.4.1.1 tarball I put together for testing; it's bad enough that I've already released a gmime-2.4.1 with nothing but parallel install fixes and that 2.4.2 will be more of the same, I'd rather not have to issue a 2.4.3).

Wednesday, July 16, 2008

Gtk+ 3.0: The Things That Make You Go "Hmmm?"

Lots of discussion about Gtk+ 3.0 lately, unfortunately there's no real discussion going on (heh).

There's the camp that is excited about API/ABI breakage and there's the camp that isn't so enthused.

I have to take the side of the "not so enthused", alongside Miguel de Icaza[1][2], Havoc Pennington and Morten Welinder: it's crazy insane to go breaking API/ABI for the sake of cleaning up the API without adding new functionality that could not be achieved by simply extending the current 2.x series.

There are definitely things that can be done to the current gtk code base without having to break the current API/ABI to achieve them, so in my humble opinion that's what should be done. Granted, eventually there will have to be a Gtk+ 3.0 which breaks API/ABI in order to add some new functionality that isn't possible to implement in 2.x, but that road can be crossed when we get there. No sense breaking it now if it isn't absolutely needed.

Even more worrying is the lack of promise to not break API/ABI again after 3.0. In fact, I've read on one of the mailing lists or somewhere that they plan on breaking API/ABI every 4-5 years after 3.0, ripping out any API's they marked as deprecated in the meantime. This is crazy. One-Flew-Over-the-Cukoo's-Nest crazy (or, if you prefer, I'm-Cukoo-For-Cocoa-Puffs crazy).

For large applications (Gnumeric, Evolution, Mozilla, Eclipse, etc), porting from 1.2 to 2.0 was a huge PITA but we all did it because (besides being young and stupid) 2.0 made a long-term commitment to maintain API/ABI compatibility going forward in addition to the fact that it added a ton of much-needed functionality (accessibility, UTF-8, model/view, and really good text layout w/ support for RTL and CJK).

If 2.0 was just 1.2 + sealed structs and the removal of some deprecated APIs, no one would have bothered with 2.0.

To respond to a point on Tim Janik's blog:

3.0 will ABI-incompatibly remove all deprecated and private APIs. Of course, the above described deprecation scheme only scales well if deprecated APIs are really removed from the code base at some point.

One reason that ISV's are typically on-board with Microsoft is that Microsoft has gone to great lengths to maintain backward compatibility with their old APIs. Joel Spolsky talks about it a bit in How Microsoft Lost the API War (specifically, the section The Two Forces at Microsoft).

The Windows testing team is huge and one of their most important responsibilities is guaranteeing that everyone can safely upgrade their operating system, no matter what applications they have installed, and those applications will continue to run, even if those applications do bad things or use undocumented functions or rely on buggy behavior that happens to be buggy in Windows n but is no longer buggy in Windows n+1.

I'm not going to argue that Gtk/GNOME should go to these extensive lengths to make sure buggy apps continue to work, but there's no reason that G*_DISABLE_DEPRECATED can't simply mean "we're not going to bugfix these anymore, what you see is what you get". You don't have to ever remove them, especially since it likely doesn't require much maintenance to keep them around. The port to Gtk+ 3.0 would require some work to make sure all the internals of things like GtkCList use accessor methods to anything that they use internally, but after that the job should be done and over with.

(ABI might not be a bit hard, but you could maintain API - thus meaning a simple recompile would work)

On the *giggle* *giggle* You should be using Mono/Gtk# *giggle* *giggle*-side, any application built against Gtk# 2.x will still work with Gtk# 3.x w/o any changes :-)

Oh, and Gtk# has DataBinding support (which, btw, does not require API/ABI breakage to Gtk+ nor sealed structs like some people seem to think on this morning's #gnome-hacker's discussion *cough* *cough*).

Friday, June 13, 2008

Linux Haters

Okay, I have to join in and say that I, too, have been enjoying Linux Hater's Blog these past few days.

He makes a lot of good points and I like his humor ;-)

Sunday, June 1, 2008

How To Survive Poisonous People

This is an interesting Google Tech Talk about how to survive poisonous people in F/LOSS communities. I probably find it interesting at least in part because there are a couple of very loud poisonous people constantly attacking the GNOME and Mono projects (both of which I'm involved with), but it's a great talk to listen to anyway.

I personally love the "Hostility" slide at around 29 minutes into the talk:

Hostility
  • Insults the status quo
  • Angrily demands help
  • Attempts to blackmail
  • Attempts to deliberately rile
  • Makes accusations of conspiracy (paranoia)

The bold/italic bit is a big hint-hint to the handful of people (not that they aren't also guilty of some of the others points) I'm referring to as the poisonous people around GNOME and Mono ;)

Tuesday, February 26, 2008

Lots of GNOME/Mono FUD Lately

It would seem that lately there are a lot of FUD-spreading trolls crawling out of the woodwork trying to frighten people into thinking that GNOME somehow depends on Mono.

Let's take a look at their most widely repeated claims:

GNOME depends on Mono

This is simply untrue... to see for yourself, try removing Mono from your Linux system using yum, zypper, or apt (or whatever) and you will plainly see that it does not remove GNOME - it may remove Tomboy, F-Spot, Banshee and/or Beagle (if you have any of them installed), but it will not remove any core components of your GNOME system.

Now that we've proven that GNOME does not depend on Mono, let's move on to their next claim:

GNOME depends on libbeagle, a Mono program

Again, false. GNOME's help browser has an optional dependency on a C-library called libbeagle which can be used to make search queries via IPC (Inter-Process-Communication) to the Beagle daemon if and only if Beagle is installed. I.E., Yelp does not depend on Beagle, it is simply able to take advantage of Beagle if it is available. As far as I'm aware, there are plans to replace libbeagle with a more generic library able to communicate with either Beagle or Tracker via IPC, depending on which one the user has installed.

NDesk-DBus is replacing DBus in GNOME

There was a big stink about this a while ago by a very angry person who didn't understand how libraries or software development in general works.

GNOME continues to depend on the C-implementation of DBus (called libdbus) and that is unlikely to change unless DBus itself (the technology, not the C-library) gets replaced.

NDesk-DBus, written by the famous Alp Toker, is a replacement for the current DBus-Sharp .NET binding around libdbus, the C-implementation. The main difference between NDesk-DBus and DBus-Sharp is that DBus-Sharp wraps libdbus while NDesk-DBus is a fully managed implementation of the DBus wire protocol.

GNOME not only does not, but it cannot, replace DBus with NDesk-DBus - any half-way competent programmer would know and understand why this is so. Native C programs cannot easily call into managed code.

Someday soon it will be practically impossible to write any app for GNOME without being forced to use MONO

Considering that in order for this to happen, core GNOME libraries would have to be rewritten in a .NET language, this is unlikely to ever happen, never mind anytime soon.

As you can plainly see, these types of claims are being made by people who do not understand the most basic concepts of software development.

GNOME is riddled with Mono applications

If by "riddled" they mean "not", then yes. ;-)

There is currently only one official GNOME application that uses Mono and that application is Tomboy. Tomboy, as useful a tool as it is, is not even arguably a core component of the GNOME desktop in that removing it will not somehow make your GNOME desktop useless.

Novell is forcing GNOME to include Mono

Ask any core GNOME developer and he or she will tell you that this is absurd. To the best of my knowledge, Novell has not even once requested that any of its Mono-based applications be accepted as core GNOME applications, never mind forced one to be accepted. I should also note that Tomboy, the only Mono application in GNOME currently, was not a Novell project at the time it as accepted for inclusion in GNOME.

This post has been brought to you by the letters G and M and the number 2.

Wednesday, February 6, 2008

Optimizing GMime's UUEncoder

This past weekend I was talking with Andreia about how Pan is built on top of GMime and takes advantage of my awesomely speedy uuencode/uudecode routines which reminded me that I had done some performance comparisons of GMime's uuencode program vs. the one in the GNU sharutils package a number of years ago.

I had compared GMime 1.90.0 (which was a pre-release of GMime 2.0) and GNU sharutils 4.2.0 and the results were pretty impressive... GMime's uuencoder was on the order of 3 times faster than the one in sharutils and produced exactly the same results.

The uudecoder and the base64 encoder/decoder were all roughly on the order of 7 times faster than those in GNU sharutils, so all around GMime outperformed GNU sharutils by quite a bit.

Anyways, re-reading my test results got me thinking that my uuencode routines could probably be optimized a bit more as they were lagging a bit behind the base64 encoder routine and there's really no reason it should be that far off.

Well, tonight I finally got off my butt and decided to take a look and figure out why. Upon scrolling down to my uuencode_step() routine, I immediately saw why:

Each loop would collect up to 3 bytes from the input and bit shift them into a 32bit 'saved' variable (which is a state variable used for incremental uuencoding an input stream). Then, if I had successfully extracted 3 bytes from the input, I would extract them out of 'saved' into 3 unsigned char variables. At this point I would then encode them into a temporary output buffer. When this output buffer ('uubuf') grew to 60 bytes, I'd flush it to the real output buffer with a memcpy().

All of this extra copying of data around adds up after a while and really begins to impact performance.

Before making any changes, I timed how long it took the original version of my uuencode_step() function to encode linux-2.6.24.tar.gz on my system[1]. An average result over numerous runs was as follows:

[fejj@localhost ~]$ time `gmime-uuencode linux-2.6.24.tar.gz linux-2.6.24.tar.gz > /dev/null`
real    0m0.470s
user    0m0.412s
sys     0m0.052s

After my rewrite, my new results were closer to:

[fejj@localhost ~]$ time `gmime-uuencode linux-2.6.24.tar.gz linux-2.6.24.tar.gz > /dev/null`
real    0m0.291s
user    0m0.252s
sys     0m0.024s

For the sake of comparison, the best time I could manage to get from GNU sharutils 4.6.2 was as follows:

[fejj@localhost ~]$ time `uuencode linux-2.6.24.tar.gz linux-2.6.24.tar.gz > /dev/null`
real    0m1.386s
user    0m1.276s
sys     0m0.092s

The new implementation of uuencode_step() in gmime/gmime-utils.c has been committed to the gmime svn module on GNOME's subversion server, revision 1216 - this change should appear in the next release of GMime which will likely be 2.2.17.

Notes:

1. The system I tested this on was my Lenovo T61 laptop w/ a 7200 RPM harddrive running OpenSuSE 10.3 with various updates. The kernel was version 2.6.22.13-0.3-bigsmp.

From /proc/cpuinfo:

model name : Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz
cpu MHz : 800.000

(e.g. my cpu was scaled down at the time of testing)

2. The GMime uuencode implementation uses a GMimeStreamFs for input as well as output. This stream class is a wrapper around the POSIX I/O system functions which unfortunately has a sub-optimal need to perform an lseek() before each read() or write() call in order to make sure that the underlying file descriptor is in the expected position. This is necessary because it is possible for multiple streams to re-use the same fd.

I mention this because an obvious rebuttal to GMime's superior performance might be to suspect that GMime's uuencode implementation "cheated" by using an mmap()'d input buffer where the GNU sharutils implementation might not.

Monday, February 4, 2008

Re: DBus OOM handling

I didn't find a way to comment on Havoc's insights on OOM error handling, so I'm posting here.

Havoc, thanks for your first hand experience on the topic! A 30-40% increase in lines of code is insane, but not far from what I expected. The fact that you discovered that most of your original OOM handling code was broken was also not a surprise (and I don't mean to suggest that your code is sub-par, but rather that it's not easy to get right unless you have test cases for each code path).

I'll have to check out the code when my eyes are a bit less strained (to the point where they are beginning to tear up), I'm am now very interested!

Sunday, February 3, 2008

Worse is Better in the form of Autosave

There's recently been some talk about how GLib is poorly designed software because g_malloc() abort()s when the underlying malloc implementation returns NULL (suggesting an OOM condition) and therefor should never be used to write real-world applications because your calling code doesn't have a chance to do proper error checking (altho it was brought up that you can actually use g_try_malloc() and/or plug in your own malloc implementation underneath g_malloc() which could trivially notify the application that an OOM condition was met before returning to g_malloc()).

While at first, this argument seems correct and you begin to think "oh my god, the sky is falling", it's important to actually stop and think about the issue a bit first.

GLib was originally a utility library written as part of the Gtk+ widget toolkit in order to make their lives easier. When designing a widget toolkit (Gtk+ in this case) for real-world programmers to use, simplicity is key. If your widget toolkit is hard to use because it offers a way to notify the application developer of every conceivable error condition, then no one would use it because it would be "too hard".

What good is a library that is too hard to use that nobody uses it? It's no good, that's what.

The problem is that the idealists complaining about glib's g_malloc() have only considered being able to check g_strdup()'s return for NULL or maybe as far as gtk_foo_new() and have not considered that the render pipeline may require allocating memory as it renders the widget which might not have an ideal way to pass the OOM error back up to the application because the top of the call stack may in fact be gtk_main() and not some callback function implemented in the application's code itself.

The idealists argue that without the ability to check every malloc() for a NULL return and chain it back up to a high enough level in the call stack to handle properly means that users could lose their unsaved document if the application is, for example, a word processor. They argue that a properly designed application will always properly handle all error conditions and pass errors back up the stack where an emergency buffer can be used to show the user an "Out of memory" error dialog and/or save all of the user's unsaved work.

The problem with this school of thought is that the simple act of rendering your error dialog may require memory that you do not have available (if we are truly OOM as opposed to simply being unable to allocate that ~4GB buffer that the application tried to allocate due to poor arithmetic).

There is one thing that they are correct on, however, and that is that losing a user's document is a Bad Thing(tm).

What they haven't considered, however, is that it's possible to prevent data loss without the need to implement their really complex OOM handling code:

I dub thee, auto-save.

Yes, I will assert that auto-save is our savior and that it is, in fact, the only feasible solution in what I affectionately refer to as: The Real World.

In the Real World, applications are built on top of other people's code that you do not control and do not have time nor luxury to audit, you simply have to trust that they work as advertised.

Let's imagine, for a minute, that you write a word processor application using some toolkit (other than Gtk+, obviously) that upholds your idealist design principles in that it is designed in such a way as to be able to notify your word processor application about OOM conditions that it experienced way down in the deep dark places of the rendering pipeline. And let's, for argument's sake, assume that your application is flawlessly written - because you are an idealist and thus your code is perfectly implemented in all aspects, obviously.

Now imagine that a user is using your word processor application and the version of the widget toolkit (s)he's using has a bug in some error handling case that is unexpectedly hit and the error doesn't properly get passed up the call stack, but instead crashes the application because the toolkit's bug corrupts some memory.

Oops.

All the hard work you did, making sure that every possible error condition in your code properly handles the error, never gets hit because the application crashed in a library you trusted to be implemented flawlessly, so the user loses his/her document that they were writing.

Your effort was all for naught in this particular case.

What's the solution? Auto-save.

What have we learned from this? Auto-save is needed even if your toolkit is sufficiently designed to pass all errors (including OOM errors) back up the stack.

Once you've implemented auto-save, though, what are all those custom OOM-checks for each and every malloc() call in your application really worth?

Zilch.

So why not use something like g_malloc() at this point?

Once your system is OOM, the only reasonable thing you can do is save any state you don't already have saved and then abort the application (not necessarily using the abort() call). But if you already have all your important state pre-saved, then all you have left to do is shut down the application (because you don't have enough memory resources to continue running).

Where does Worse is Better come in, you ask?

Well, arguably, the auto-save approach isn't as ideal as implementing proper fallback code for every possible error condition.

Auto-save is, however, Better because it works in the Real World and is Good Enough in that it achieves the goal of preventing the loss of your user's document(s) and because it is far easier to implement with a lot fewer points of failure.

Fewer points of failure means that it is a lot more likely to work properly. By using the auto-save approach, you can focus on making that code robust against every conceivable error condition with far less developer time and resources meaning you are able to keep both cost and data loss down which makes everyone happy.

Thursday, December 6, 2007

gnome-volume-manager-2.22.0

Just released gnome-volume-manager-2.22.0 - a bit early for GNOME 2.22, but seeing as how I rarely ever hack on this project anymore, I figured I should actually release a new version (last release was 2.17.0 from presumably a year or more ago).

This new release adds integration with ConsoleKit for detecting whether the user is local and whether or not he/she is active at the console.

The other major change it includes is the ability to execute autorun.exe and autorun.inf files on cdroms so long as wine is installed on the system.

I implemented this feature toward the end of the summer because I had attempted to help my grandmother migrate from Windows95 to Linux. Unfortunately, while she was OK with the GNOME desktop itself for the most part, she wasn't comfortable using OpenOffice (she wanted Microsoft Office 97) and she wanted to use the proprietary versions of Mahjongg/Sudoku/etc games that she was used to running on her old Windows95 machine. As I began to show her how to install/run Windows software under Linux using wine, I realized that the process could be a whole lot simpler/intuitive than it was by making gnome-volume-manager auto-magically run autorun.exe and autorun.inf files under wine for her when she plopped the cd into the drive.

...and the rest is, as they say, history.

Code Snippet Licensing

All code posted to this blog is licensed under the MIT/X11 license unless otherwise stated in the post itself.