Introduction to GLib Low Memory Handler

The default behavior of GLib in Linux is such that in case of a memory allocation failure, the GLib memory allocation API will call abort and hence terminate the application.

Memory allocation failures are more likely on a mobile device and aborting the application in such cases is undesirable. Therefore, the implementation of GLib for Symbian platform has been modified so that the GLib memory allocation APIs return NULL and do not call abort(). This requires the application written using GLib to start handling memory allocation failures which they are currently not doing.

If the user, for example, wants to change the first character of a string with z and return the string to the caller a GLib code for this can be written as follows:

gchar * f1(gchar * x) 
{ 
 	  gchar *temp; 
    temp = g_strdup(x); 
    temp[0] = ā€˜zā€™; 
    return temp; 
}

If there is a memory allocation failure in Linux, the call to g_strdup which internally uses g_malloc will cause the application to abort. However, in Symbian platform the g_malloc() function will return NULL, but the implementation of g_strdup() is such that the return value of g_malloc() is not checked for NULL. This causes the g_strdup() API to panic or crash the application. Thus, a mechanism to deal with the failures, panics or crash resulting from low memory situations within Symbian platform is needed.

Illustration of the mechanism to handle a memory allocation failure scenario

The user needs to initialize the framework which handles the low memory scenarios using the below-mentioned macros:

  1. SET_LOW_MEMORY_TRAP(failure_value): This macro will set a trap handler for low memory cases. In case there is an allocation failure, the failure value will be returned from the function where the trap handler is set.

  2. SET_LOW_MEMORY_TRAP_VOID(): This will do the same as the above except that the function where this is set will just return. This will typically be used by functions which return void. In this case, however, the caller must check the errno value. If it is ENOMEM, then the user must handle things appropriately.

  3. REMOVE_LOW_MEMORY_TRAP(): This will remove the trap handler which was set.

The function f1() will now be rewritten as:

#include <glowmem>
gchar * f1(gchar * x) 
{ 
	gchar *temp; 
  SET_LOW_MEMORY_TRAP(NULL); 
  temp = g_strdup(x); 
	temp[0] = ā€˜zā€™; 
	REMOVE_LOW_MEMORY_TRAP(): 
	return temp; 
} 

If there is a memory allocation failure when the above function f1() is called, then f1() will return NULL to its caller. The caller of f1() is expected to check the failure value of f1() instead of ignoring the same.

Some words of caution: The macro SET_LOW_MEMORY_TRAP() defines a variable so it is necessary to make the call after all the local variables declarations in C. REMOVE_LOW_MEMORY_TRAP() must be called just before the return from the function, which means that if there are four return statements in the function then all of them must be preceded with a call to REMOVE_LOW_MEMORY_TRAP().