[gstreamermm] Gst::Pad: added exception handler for callback calls



commit 2c3f4fb2ba95755784406ab319011c52a409054f
Author: Marcin Kolny <marcin kolny flytronic pl>
Date:   Thu Aug 21 23:36:44 2014 +0200

    Gst::Pad: added exception handler for callback calls
    
    Sometimes we can't use default glibmm exception handler, because handler
    must be registered in the same thread. There is a few methods, where it's
    impossible to register handler, because we don't have an access to this
    thread.
    
        * gstreamer/src/pad.ccg: exception handler implementation, call
          exception handler in catch(...) blocks.
        * gstreamer/src/pad.hg: exception handler method header

 gstreamer/src/pad.ccg |   58 +++++++++++++++++++++++++++++++++++++++++-------
 gstreamer/src/pad.hg  |    5 ++++
 2 files changed, 54 insertions(+), 9 deletions(-)
---
diff --git a/gstreamer/src/pad.ccg b/gstreamer/src/pad.ccg
index 0ac5f89..7dc2e2d 100644
--- a/gstreamer/src/pad.ccg
+++ b/gstreamer/src/pad.ccg
@@ -24,6 +24,8 @@
 #include <gstreamermm/event.h>
 #include <gstreamermm/padtemplate.h>
 #include <gstreamermm/iterator.h>
+#include <gstreamermm/message.h>
+#include <gstreamermm/bus.h>
 
 _PINCLUDE(glibmm/private/object_p.h)
 _PINCLUDE(gstreamermm/private/object_p.h)
@@ -36,14 +38,14 @@ extern "C"
 static GstPadProbeReturn Pad_Probe_gstreamermm_callback(GstPad* pad, GstPadProbeInfo* probe_info, void* data)
 {
   Gst::Pad::SlotProbe* the_slot = static_cast<Gst::Pad::SlotProbe*>(data);
-
+  Glib::RefPtr<Gst::Pad> pad_wrapper = Glib::wrap(pad, true);
   try
   {
-      return static_cast<GstPadProbeReturn>((*the_slot)(Glib::wrap(pad, true), Glib::wrap(probe_info, 
true)));
+      return static_cast<GstPadProbeReturn>((*the_slot)(pad_wrapper, Glib::wrap(probe_info, true)));
   }
   catch(...)
   {
-    Glib::exception_handlers_invoke();
+    pad_wrapper->exception_handler();
   }
 
   return GST_PAD_PROBE_DROP;
@@ -94,6 +96,44 @@ Pad::Pad(const Glib::RefPtr<const Gst::PadTemplate>& templ)
       "construct pad from null template.");
 }
 
+void Pad::exception_handler()
+{
+  Glib::RefPtr<Element> parent = parent.cast_dynamic(get_parent());
+  
+  if (!parent)
+  {
+    puts ("nie postuje buga");
+    Glib::exception_handlers_invoke();
+    return;
+  }
+
+  Glib::RefPtr<Message> error_msg;
+
+  try
+  {
+    throw;
+  }
+  catch(const Glib::Error& error)
+  {
+    Glib::Error err = error;
+    error_msg = MessageError::create(parent, err, "glibmm exception");
+  }
+  catch(const std::exception& ex)
+  {
+    Glib::Error err(GST_CORE_ERROR, GST_CORE_ERROR_FAILED, ex.what());
+    error_msg = MessageError::create(parent, err, "standard exception");
+  }
+  catch(...)
+  {
+    Glib::Error err(GST_CORE_ERROR, GST_CORE_ERROR_FAILED, "");
+    error_msg = MessageError::create(parent, err, "unknown error type");
+  }
+
+  puts ("postuje buga");
+  int out = parent->post_message(error_msg);
+  printf ("na port: %d\n", out);
+}
+
 gulong Pad::add_probe(PadProbeType mask, const SlotProbe& slot)
 {
     SlotProbe* slot_copy = new SlotProbe(slot);
@@ -187,7 +227,7 @@ GstFlowReturn Pad::Pad_Chain_gstreamermm_callback(GstPad* pad, GstObject*, GstBu
   }
   catch(...)
   {
-    Glib::exception_handlers_invoke();
+    pad_wrapper->exception_handler();
   }
 
   return GST_FLOW_ERROR;
@@ -216,7 +256,7 @@ gboolean Pad::Pad_Query_gstreamermm_callback(GstPad* pad, GstObject*, GstQuery*
   }
   catch(...)
   {
-    Glib::exception_handlers_invoke();
+    pad_wrapper->exception_handler();
   }
 
   return false;
@@ -240,7 +280,7 @@ gboolean Pad::Pad_Event_gstreamermm_callback(GstPad* pad, GstObject*, GstEvent*
   }
   catch(...)
   {
-    Glib::exception_handlers_invoke();
+    pad_wrapper->exception_handler();
   }
 
   return false;
@@ -261,7 +301,7 @@ gboolean Pad::Pad_Activate_gstreamermm_callback(GstPad* pad, GstObject*)
   }
   catch(...)
   {
-    Glib::exception_handlers_invoke();
+    pad_wrapper->exception_handler();
   }
 
   return false;
@@ -282,7 +322,7 @@ gboolean Pad::Pad_Activatemode_gstreamermm_callback(GstPad* pad, GstObject*, Gst
   }
   catch(...)
   {
-    Glib::exception_handlers_invoke();
+    pad_wrapper->exception_handler();
   }
 
   return false;
@@ -305,7 +345,7 @@ GstFlowReturn Pad::Pad_Getrange_gstreamermm_callback(GstPad* pad, GstObject*, gu
   }
   catch(...)
   {
-    Glib::exception_handlers_invoke();
+    pad_wrapper->exception_handler();
   }
 
   return GST_FLOW_ERROR;
diff --git a/gstreamer/src/pad.hg b/gstreamer/src/pad.hg
index b875b8d..0366de8 100644
--- a/gstreamer/src/pad.hg
+++ b/gstreamer/src/pad.hg
@@ -412,6 +412,11 @@ public:
   bool is_ghost_pad() const;
   bool is_proxy_pad() const;
 
+  /**
+   * Handle exceptions occuring in callback methods
+   */
+  void exception_handler();
+
 private:
   SlotChain slot_chain;
   SlotEvent slot_event;


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