Archive | GError RSS for this section

Forking A New Process Using GLib

These days we tend to think of concurrency in terms of spawning threads. Need to perform a long running calculation? Spawn a thread. However, there are other ways; we can fork and create a new process. Unfortunately for us, fork and threads don’t play nice together. How so, you ask? When you fork a new process, only the current thread is copied into the new process. If any other thread held a lock on a mutex, that mutex will never be unlocked in the new process. This includes mutexes held by system calls such as malloc.

In light of this, you may be wondering why I’m wasting your time with this. No, this isn’t just a PSA, there is something sane you can do with fork in a multi-threaded world: you can call exec and friends. And it just so happens that GLib can help us with this. GLib provides us with Process Spawning facilities that integrate with GIOChannel and GMainLoop.

The first thing you may notice is that there isn’t actually a GLib equivalent to fork or exec. These two calls are combined into the g_*_spawn_* family of functions. The reason for this is because GLib itself spawns threads to perform work. By default, *all* GLib applications potentially have threads running and as such it is never safe to call fork without immediately calling exec.

Forking A New Process

First, let’s do some setup:

gchar * child_argv[] = {"[PROGRAM_TO_RUN]", "[ARGUMENTS]", NULL}

This is the command that will be executed (Your argv). Since this array is terminated by NULL, GLib is able to determine its length and we do not need an argc.

GPid pid; gint stdout; GError * error = NULL;

We’ll need these as well. Now, it’s time to start our process:

gboolean result = g_spawn_async_with_pipes (NULL, child_argv, NULL, G_SPAWN_DEFAULT, NULL, NULL, &pid, NULL, &stdout, NULL, &error);

Yeah… That one’s a doosey. Let’s go over all those fields.

The first argument is the child’s working directory. If this is NULL, then the child inherits the parent’s working directory.

The second argument is the child’s argument vector. This is the command that will be executed.

The third argument is the child’s environment. Like the argv, this must be NULL-terminated. If NULL the child inherits the parent’s environment.

The fourth argument is the child’s spawn flags.

The fifth argument is a pointer to a GSpawnChildSetupFunc function, to be called just before exec. If null, then the process will fork and exec without additional setup.

The sixth argument is the gpointer to be passed to the GSpawnChildSetupFunc.

The seventh argument is a location to return the PID of the new process.

The eighth, ninth, and tenth arguments are return locations for the file descriptors of STDIN, STDOUT, and STDERR respectively.

The last argument is a return location for a GError if something goes wrong. This function returns FALSE if something goes wrong.

What Now

So you’ve got your fancy new process, what do you do with it?

Well, first let’s create some GIOChannels using our file descriptors:

GIOChannel * outch = g_io_channel_unix_new(stdout);

Next, we add callbacks:

GSource * stdout_source = g_io_create_watch( outch, G_IO_IN); g_source_set_callback(stdout_source, stdout_callback, outch, NULL); g_source_attach(stdout_source, main_context); GSource * stdout_abort = g_io_create_watch( outch, G_IO_ERR | G_IO_HUP | G_IO_NVAL); g_source_set_callback(stdout_abort, abort_callback, NULL, NULL); g_source_attach(stdout_abort, main_context);

Here, I’ve created two sources: one that will be called when there’s data to be read, and one to be called when something goes wrong. The first call to g_io_create_watch creates a GSource that watches for a certain condition. The second call to g_source_set_callback tells the watch what function to call when the condition is met. This function should have the following signature:

static gboolean callback(gpointer data)

The final call to g_source_attach attaches a source to a GMainContext. If NULL is passed to the second argument, then the default context is used.

…and that’s all there is to it! Your callbacks can operate on file descriptors using the g_io_channel_* family of functions, and when the abort callback is called, it can exit gracefully.

DMP Photo Booth: Deep Magick

After working on DMP Photo Booth for a few months, the day came when I needed to implement actual functionality. It’s the day we all dread, but for me this was no longer some looming menace; it was time to stop fiddling around in my framework and actually build on it.

More specifically, it was time to figure out how to turn ~5 images and a background into a photo strip. After checking to make sure GLib and GTK didn’t provide this functionality (GdkPixbuf almost cuts it, but as far as I can tell, it can’t layer images over each other), I turned to google. After some time, I settled on my library: ImageMagick.

ImageMagick bills itself as sort of a command-line PhotoShop. I was suspicious as well, but that’s neither here nor there. The thing about ImageMagick that interested me is its language bindings. ImageMagick provides a library for many languages, including two for C: MagickCore for “Wizard-level developers” and MagickWand for us chumps. Being a chump, I decided to go with MagickWand.

NetBeans configuration

This was relatively straightforward. If you got GTK set up, this should be no problem for you. First, ensure you have the WagickWand development headers. On Ubuntu, this can be accomplished by the following command:

sudo apt-get install libmagickwand5 libmagickwand-dev

On my system, libmagickwand5 was already installed, so I downloaded the headers and got to work.

Next, in NetBeans click Tools->Options, click on the C/C++ tab, and click on Code Assistance. Add the location of the ImageMagick headers (/usr/include/ImageMagick for me). Click OK.

Next, we need to set up our project. Right click your project and click Properties. Click Build->C Compiler. Under Additional Options, add MagickWand to your pkg-config --cflags string. Click Build->Linker and do the same with your pkg-config --libs string.

You are now ready to conjure some magick!

Conjuring Some Magick

Now, let us put on our robes and wizard hats; it’s time to do some magick! Let’s go over a function that will overlay a resized image over a larger background. You can find the actual production photo strip function on Github.

void cast_magick_spell() { MagickWandGenesis(); ...

Before we can do anything, we must initialize MagickWand. “MagickWandGenesis()”, you ask? Of course the function would be called MagickWandGenesis, what kind of silly question is that?

... MagickWand * background_wand = NewMagickWand(); MagickWand * working_wand = NewMagickWand(); MagickWand * final_wand = NULL; ...

The MagickWand * is the main object passed around in a MagickWand application. Working with MagickWand requires some juggling of these pointers, which is why we have 3 of them.

... if (!MagickReadImage(background_wand, "/tmp/background.jpg") { ...

This function reads an image from a file. It returns MagickTrue on success, and MagickFalse on failure. If it returns MagickFalse, we have some clean-up to do…

... ExceptionType exception_error_code; char * exception_message = MagickGetException( background_wand, &exception_error_code); ...

MagickWand makes use of “Exceptions” throughout, so if a function fails, you can most likely pull an exception out of it using MagickGetException. Like any exception, it is up to you what to do with them. Since I’m using GLib, I’ve been wrapping them in a GError and propagating them up. This is actually very easy to do; your error code and message are already there. All you need to do is G_DEFINE_QUARK your error quark and throw it in there. For the purposes of this function, I’m just going to use printf, do some cleanup, and return.

... printf("Oh no! Exception %d: %s\n", exception_error_code, exception_message); MagickRelinquishMemory(exception_message); DestroyMagickWand(background_wand); DestroyMagickWand(working_wand); return; } ...

Nothing particularly shocking here. We printf our message, free the exception_message string using MagickRelinquishMemory, free our MagickWands using DestroyMagickWand, and return.

Assuming we make it past this block, background_wand now contains the background image. Next, we load the foreground image:

... if (!MagickReadImage(working_wand, "/tmp/foreground.jpg") { /* * Exception handling omitted * for brevity. You should still * do it here... */ } if (!MagickResizeImage(working_wand, [WIDTH], [HEIGHT], LanczosFilter, [BLUR])); { /* More error checking... */ } ...

After loading the foreground image, and doing our error checking we attempt to resize the image using MagickResizeImage. This function takes several parameters:

  • MagickWand * working_wand: The MagickWand to operate on
  • size_t [WIDTH]: the width to set the image to
  • size_t [HEIGHT]: the height to set the image to
  • FilterTypes LanczosFilter: the filter to use to resize. There are a list of them in the API documentation. Discussion of these is outside the scope of this post.
  • double [BLUR]: The blur factor to apply. 1.0 is no change. The further 1.0, the blurrier the resulting image.

Like many calls in this library, this function can return MagickTrue or MagickFalse. If it returns MagickFalse, something threw… Next, we adjust the position of the image…

... if (!MagickResetImagePage(working_wand, [RELATIVE_PAGE_SPECIFIER])) { /* * You'd think one of these wizards * could have written a function that * doesn't throw... */ } ...

This function takes some explaining. The second parameter: char * [RELATIVE_PAGE_SPECIFIER] is what’s doing the work here. This is a Magickally formatted string that looks like this: "100x100+15+15!". Let’s examine this as a printf formatting string:

"%dx%d+%d+%d!"

We have 4 integer tokens here. The first token is canvas width, and the second is the canvas height. Note that these will not resize the image, so don’t get any bright ideas about eliminating the previous resize call. The third and fourth tokens are offset from X and Y respectively. These are what we’re really concerned about here. This will allow us to position our foreground image over the background.

Also, don’t forget to check for exceptions!

... MagickSetLastIterator(background_wand); if (!MagickAddImage(background_wand, working_wand)) { /* exceptional! */ } ...

We’re almost there! Now we have to add the images from working_wand to background_wand. These MagickWand objects are lists of images. Like most lists, they have iterators. The call to MagickSetLastIterator sets background_wand’s iterator to the last image in the list. Any images add will be added after this image. next we call MagickAddImage which adds copies of working_wand’s images into background_wand. As before, don’t forget to check for exceptions.

... final_wand=MagickCoalesceImages(background_wand); if (!final_wand) { /* You guessed it! */ } MagickSetLastIterator(final_wand); ...

Now we need to combine all our images into one single image. This is accomplished by calling MagickCoalesceImages which returns a new MagickWand with all of our images combined into 1. The MagickWand used for this call remains unaffected. Obviously, if final_wand == NULL, something threw.

After this is done, we need to set the iterator of final_wand to the Last Iterator, or the next step doesn’t work as advertised…

... if (!MagickWriteImage(final_wand, "/tmp/final.jpg")) { /* wait for it! */ } ...

Shockingly, this function writes your new image to a file. Make sure you check your exceptions.

... DestroyMagickWand(background_wand); DestroyMagickWand(working_wand); DestroyMagickWand(final_wand); MagickWandTerminus(); }

…and were done! Clean up your pointers and call MagickWandTerminus to finalize the MagickWand library. If you browse to /tmp, you should have a newly created final.jpg if all was well!

Would I Do It Again?

Sure.

ImageMagick was a decently easy to work with library. The documentation wasn’t amazing, but it was tolerable. I’m still a little hazy on the use of the [RELATIVE_PAGE_SPECIFIER], but it’s working so far. One nice thing about the docs is that there are many examples. If the docs don’t explain something, you can look up an example and get an idea of how things work.

The only really big issue I have with this library is how it handles exceptions. This is an issue that I’ve touched on before; it is all too easy to forget to check a return code. I went down that road with DMP Photo Booth, and I’ve since rejected it. I spent an entire day refactoring my program to use GError.

MagickWand has exceptions, they’re just really easy to ignore. While writing this blog post, I caught several instances of unchecked return values in my 1 function that uses MagickWand. Tomorrow I plan to fix this, but it’s time I could be spending on something else.

If GError is Java’s checked exceptions with all it’s order and verbosity, then MagickWand’s exceptions are the Wild Wild West of C++’s unchecked exceptions. If you’ve spent any time working with C++, this has almost certainly bit you; some function doesn’t document if it throws, and your program magickally starts crashing because you didn’t catch something. Bad times are had by all. Sure, you could throw a try/catch block in main() and catch all exceptions to keep from crashing, but at that point your program is a dead man walking. Best to put it out of its misery…

Personally, if I ever write a personal project in C++ again, I’m likely to disable exceptions in my program; they’re just more effort than they’re worth. Maybe I’d even use GError in my C++ app if I could convince myself that I’m not a bad person for using a C library in C++.

Regardless, one blemish on an otherwise pleasant experience is no big deal. Here’s to a successful foray into the land of High Adventure!

DMP Photo Booth: Throw It All Out

Another week goes by, another major refactor. This time on the chopping block: return codes. As you may know if you’ve been following development, I’ve been using integer return values to indicate success and failure of functions. This was working for a while, but as we all know, the worst problems don’t rear their ugly heads until some time has gone by. After working around them, I’ve realized this strategy has 3 main issues:

  • It’s really easy to just not check the return value, and not notice when some function returns DMP_PB_OMG_WERE_ALL_GONNA_DIE
  • It can be problematic if you have to return an integer as an actual result
  • You have to settle on some “failure” return value for functions that return values, and this can be a problem if you can’t guarantee some value will never be valid

Too bad I didn’t pick a modern language with exception handling…

GError To The Rescue

Luckily for me, GLib has the answer once again. GLib has a feature called GError, that is its answer to exception handling. I’d tell you all about how to use GError, but there is no need. GLib’s documentation is on par with Java’s documentation, and the GError documentation page is a shining example of how good documentation can make the difference between good and great.

Seriously, if anybody from Gnome is reading this: thank you for writing some decent documentation. This is a huge pet peeve of mine. No, your function called do_stuff(some_struct * zanzibar) is not self documenting, because if you don’t write a comment telling me if it has side effects, or if I remain responsible for zanzibar, then I have to look at your code to be sure. But I digress…

The basic idea behind GError is that any function that can throw has a GError ** as its final argument. If you’d like to call a function that can throw, you need to pass in an unallocated pointer to the function:

void some_func() { GError * error = NULL; dangerous_func(&error); ...

At this point, dangerous_func will be called, and return. Afterwards, if your GError pointer is no longer NULL, then an exception was thrown:

if (error != NULL) { //what now? }

This test is equivalent to a catch {} block. At this point, you traditionally have 3 options: Handle the exception, re-throw the exception, or wrap the exception in some other exception type and throw.

Personally, I’m a huge fan of Java’s checked exceptions. Sure, it can be annoying having to catch 15 different exceptions because some library author thought they needed that many on one method, but it sure beats having to magically know if some function throws, as C++ handles things. I feel that GError strikes a good balance. If a function has a GError ** argument, then it throws. At this point, you can check the docs to see if the author felt fit to say what GErrors they set, or you can just read the error and see what it is. You don’t have to catch some specific Exception class as in traditional exception handling, and you can determine exception type without resorting to instanceof.

Now, let’s examine our options…

Handle It

if (error != NULL) { printf("%s %d: %s\n", g_quark_to_string(error->domain), error->code, error->message); g_error_free(error); }

A GError has 3 public fields: domain, code, and message. Domain is a GQuark that is [NAMESPACE]_[MODULE]_ERROR. Think of this as your exception base class: i.e. BaseBeanFactoryBeanException. Code is an integer that represents a specific error. Think of this as your derived exception class: i.e. FluffyPinkBeanFactoryBeanException Finally, we have message. This is a human readable message for the error, and is equivalent to a Java call to Exception.getMessage().

GError has a few methods to ease working with these, but any C programmer worth their salt should be able to “make do” with these 3 fields.

Re-throw It

if (error != NULL) { g_propagate_error(this_funcs_gerror, error); return; }

Yes, it is that simple. Of course, in this case, the function signature would be:

void some_func(GError ** this_funcs_gerror)

…but aside from that, there’s not much going on here. The GError will be copied into the passed-in GError **. At this point you can (must) return; the error is now the caller’s problem!

Wrap It

if (error != NULL) { g_set_error(this_funcs_gerror, error->domain, error->code, "I know better, so I'm wrapping this!\n"); g_error_free(error); return; }

Pretty self-explanatory. As with re-throwing the exception, this requires a modified function signature. Also, this is how you’d throw a new exception as well, minus the call to g_error_free.

The Empty Catch Block

We’re all guilty of this, don’t try to act like you’re not. It’s just so much easier to do this:

try { fancyObj.someDangerousMethod(); } catch (Exception ex) {}

Don’t worry, you’re among friends. GLib has you covered on this front as well. If you pass NULL to a function that throws, it will not attempt to set an error, and you can just go on with your life:

void some_func() { dangerous_func(NULL); //catch (Exception ex) {} }

Feel free to omit that comment, I promise it’ll still work. As we all know, sometimes you just don’t care about some exception. In these cases, you aren’t forced to care, you can just pass NULL and get on with your life.

%d bloggers like this: