[banshee] libbanshee: Work-around Mono crash under FreeBSD



commit 02425e05fb44b62740ed2125edd45ea901e628a2
Author: Alexander Kojevnikov <alexander kojevnikov com>
Date:   Sun Oct 17 19:52:38 2010 +1100

    libbanshee: Work-around Mono crash under FreeBSD
    
    Mono segfaults when native code calls a managed callback from
    a different thread (see bnc#647248). This commit fixes the crash
    in banshee_log() by proxying the callback into the main thread.
    
    Note that crashes in bp_about_to_finish_callback() and
    bp_volume_changed_callback() are not yet fixed.

 libbanshee/banshee-gst.c |   40 ++++++++++++++++++++++++++++++++++++++--
 1 files changed, 38 insertions(+), 2 deletions(-)
---
diff --git a/libbanshee/banshee-gst.c b/libbanshee/banshee-gst.c
index 48d8b0a..cfd88ca 100644
--- a/libbanshee/banshee-gst.c
+++ b/libbanshee/banshee-gst.c
@@ -105,9 +105,41 @@ banshee_get_version_number ()
     return (guint)banshee_version;
 }
 
+typedef struct {
+    BansheeLogType type;
+    const gchar *component;
+    gchar *message;
+} BansheeLogHandlerData;
+
+static gboolean
+banshee_log_handler_proxy (gpointer user_data)
+{
+    BansheeLogHandlerData *data;
+
+    g_return_val_if_fail (user_data, FALSE);
+
+    data = user_data;
+    (banshee_log_handler) (data->type, data->component, data->message);
+    return FALSE;
+}
+
+static void
+banshee_log_handler_notify (gpointer user_data)
+{
+    BansheeLogHandlerData *data;
+
+    g_return_if_fail (user_data);
+
+    data = user_data;
+    g_free (data->message);
+    g_free (data);
+}
+
 static void
 banshee_log (BansheeLogType type, const gchar *component, const gchar *message)
 {
+    BansheeLogHandlerData *data;
+
     if (banshee_log_handler == NULL) {
         switch (type) {
             case BANSHEE_LOG_TYPE_WARNING: g_warning ("%s: %s", component, message); break;
@@ -116,8 +148,12 @@ banshee_log (BansheeLogType type, const gchar *component, const gchar *message)
         }
         return;
     }
-    
-    (banshee_log_handler) (type, component, message);
+
+    data = g_new (BansheeLogHandlerData, 1);
+    data->type = type;
+    data->component = component;
+    data->message = g_strdup (message);
+    g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, banshee_log_handler_proxy, data, banshee_log_handler_notify);
 }
 
 void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]