Patch proposal: libnotify and dynamically linked modules

View: New views
1 Messages — Rating Filter:   Alert me  

Patch proposal: libnotify and dynamically linked modules

by Holger Berndt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I am experiencing problems with libnotify when used from a dynamically
loaded module. Once notify_init() is called from the module, the program
crashes when the module is unloaded again.

I assume the problem lies in the call to g_atexit() during
notify_init(). The glib reference manual says on g_atexit():
 
,----
| The behaviour of atexit() in the context of dynamically loaded modules is not
| formally specified and varies wildly.
|
| On POSIX systems, calling g_atexit() (or atexit()) in a dynamically loaded
| module which is unloaded before the program terminates might well cause a
| crash at program exit.
`----

(Source:
http://developer.gnome.org/doc/API/2.0/glib/glib-Miscellaneous-Utility-Functions.html#g-atexit)

In fact, I was able to reproduce crashes with simple calls to
g_atexit() in the module, without libnotify being involved at all.

I therefore propose to offer the possibility of initializing libnotify
without g_atexit() being called. A program doing that would of course
have to take care of calling notify_uninit() itself. Please see
attached patch for a possible solution that doesn't break the current
libnotify API. It introduces an additional init function called
notify_init_auto_uninit(), and makes notify_init() a wrapper around it.
(Patch against libnotify version 0.4.2).

This problem is a little surprising, because I assumed my configuration
(a notification plugin for an application, the whole thing
running on Linux) to be a rather typical one. So if any (portable) fixes
or workarounds already exist, I'd appreciate a hint.

Thanks and greetings,
Holger

[no_atexit_notify.c.patch]

--- libnotify/notify.c.orig 2006-08-08 22:33:15.000000000 +0200
+++ libnotify/notify.c 2006-08-08 22:46:56.000000000 +0200
@@ -44,12 +44,29 @@
  * @app_name: The name of the application initializing libnotify.
  *
  * Initialized libnotify. This must be called before any other functions.
+ * The library is uninitialized automatically on program exit.
  *
  * Returns: %TRUE if successful, or %FALSE on error.
  */
 gboolean
 notify_init(const char *app_name)
 {
+ return notify_init_auto_uninit(app_name, TRUE);
+}
+
+/**
+ * notify_init_auto_uninit:
+ * @app_name: The name of the application initializing libnotify.
+ * @auto_uninit: %TRUE if the library should get uninitialized automatically,
+ *               %FALSE if the library needs to be uninitialized manually.
+ *
+ * Initialized libnotify. This must be called before any other functions.
+ *
+ * Returns: %TRUE if successful, or %FALSE on error.
+ */
+gboolean
+notify_init_auto_uninit(const char *app_name, gboolean auto_uninit)
+{
  GError *error = NULL;
  DBusGConnection *bus = NULL;
 
@@ -89,7 +106,8 @@
  G_TYPE_UINT, G_TYPE_STRING,
  G_TYPE_INVALID);
 
- g_atexit(notify_uninit);
+ if (auto_uninit)
+ g_atexit(notify_uninit);
 
  _initted = TRUE;
 


[no_atexit_notify.h.patch]

--- libnotify/notify.h.orig 2006-08-08 22:47:34.000000000 +0200
+++ libnotify/notify.h 2006-08-08 22:46:50.000000000 +0200
@@ -40,6 +40,17 @@
 gboolean notify_init(const char *app_name);
 
 /**
+ * Initializes the notifications library.
+ *
+ * @param app_name    The application name.
+ * @param auto_uninit TRUE if the library should get uninitialized automatically.
+ *
+ * @return TRUE if the library initialized properly and a connection to a
+ *         notification server was made.
+ */
+gboolean notify_init_auto_uninit(const char *app_name, gboolean auto_uninit);
+
+/**
  * Uninitializes the notifications library.
  *
  * This will be automatically called on exit unless previously called.


_______________________________________________
galago-devel mailing list
galago-devel@...
http://lists.freedesktop.org/mailman/listinfo/galago-devel