X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstbus.c;h=df2351f3e94ea73a4e78f2a6145df3fa8dbbab6c;hb=b89b1802df44829a0c034db5807bc893ad3c7774;hp=b8c2995ddbee9d2d4d9de581255d4d72b03ee7c1;hpb=e11539c30b51a9872c16765b01ab81dfe264505f;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstbus.c b/gst/gstbus.c index b8c2995..df2351f 100644 --- a/gst/gstbus.c +++ b/gst/gstbus.c @@ -21,6 +21,7 @@ /** * SECTION:gstbus + * @title: GstBus * @short_description: Asynchronous message bus subsystem * @see_also: #GstMessage, #GstElement * @@ -79,6 +80,12 @@ #include "gstbus.h" #include "glib-compat-private.h" +#ifdef G_OS_WIN32 +# ifndef EWOULDBLOCK +# define EWOULDBLOCK EAGAIN /* This is just to placate gcc */ +# endif +#endif /* G_OS_WIN32 */ + #define GST_CAT_DEFAULT GST_CAT_BUS /* bus signals */ enum @@ -122,7 +129,7 @@ struct _GstBusPrivate }; #define gst_bus_parent_class parent_class -G_DEFINE_TYPE (GstBus, gst_bus, GST_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_PRIVATE (GstBus, gst_bus, GST_TYPE_OBJECT); static void gst_bus_set_property (GObject * object, @@ -210,21 +217,16 @@ gst_bus_class_init (GstBusClass * klass) G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, G_STRUCT_OFFSET (GstBusClass, message), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_MESSAGE); - - g_type_class_add_private (klass, sizeof (GstBusPrivate)); } static void gst_bus_init (GstBus * bus) { - bus->priv = G_TYPE_INSTANCE_GET_PRIVATE (bus, GST_TYPE_BUS, GstBusPrivate); + bus->priv = gst_bus_get_instance_private (bus); bus->priv->enable_async = DEFAULT_ENABLE_ASYNC; g_mutex_init (&bus->priv->queue_lock); bus->priv->queue = gst_atomic_queue_new (32); - /* clear floating flag */ - gst_object_ref_sink (bus); - GST_DEBUG_OBJECT (bus, "created"); } @@ -278,9 +280,12 @@ gst_bus_new (void) { GstBus *result; - result = g_object_newv (gst_bus_get_type (), 0, NULL); + result = g_object_new (gst_bus_get_type (), NULL); GST_DEBUG_OBJECT (result, "created new bus"); + /* clear floating flag */ + gst_object_ref_sink (result); + return result; } @@ -515,8 +520,24 @@ gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout, gst_atomic_queue_length (bus->priv->queue)); while ((message = gst_atomic_queue_pop (bus->priv->queue))) { - if (bus->priv->poll) - gst_poll_read_control (bus->priv->poll); + if (bus->priv->poll) { + while (!gst_poll_read_control (bus->priv->poll)) { + if (errno == EWOULDBLOCK) { + /* Retry, this can happen if pushing to the queue has finished, + * popping here succeeded but writing control did not finish + * before we got to this line. */ + /* Give other threads the chance to do something */ + g_thread_yield (); + continue; + } else { + /* This is a real error and means that either the bus is in an + * inconsistent state, or the GstPoll is invalid. GstPoll already + * prints a critical warning about this, no need to do that again + * ourselves */ + break; + } + } + } GST_DEBUG_OBJECT (bus, "got message %p, %s from %s, type mask is %u", message, GST_MESSAGE_TYPE_NAME (message), @@ -738,6 +759,31 @@ no_replace: } } +/** + * gst_bus_get_pollfd: + * @bus: A #GstBus + * @fd: (out): A GPollFD to fill + * + * Gets the file descriptor from the bus which can be used to get notified about + * messages being available with functions like g_poll(), and allows integration + * into other event loops based on file descriptors. + * Whenever a message is available, the POLLIN / %G_IO_IN event is set. + * + * Warning: NEVER read or write anything to the returned fd but only use it + * for getting notifications via g_poll() or similar and then use the normal + * GstBus API, e.g. gst_bus_pop(). + * + * Since: 1.14 + */ +void +gst_bus_get_pollfd (GstBus * bus, GPollFD * fd) +{ + g_return_if_fail (GST_IS_BUS (bus)); + g_return_if_fail (bus->priv->poll != NULL); + + *fd = bus->priv->pollfd; +} + /* GSource for the bus */ typedef struct @@ -840,7 +886,7 @@ static GSourceFuncs gst_bus_source_funcs = { * a message is on the bus. After the GSource is dispatched, the * message is popped off the bus and unreffed. * - * Returns: (transfer full): a #GSource that can be added to a mainloop. + * Returns: (transfer full) (nullable): a #GSource that can be added to a mainloop. */ GSource * gst_bus_create_watch (GstBus * bus) @@ -926,6 +972,9 @@ gst_bus_add_watch_full_unlocked (GstBus * bus, gint priority, * from @func. If the watch was added to the default main context it is also * possible to remove the watch using g_source_remove(). * + * The bus watch will take its own reference to the @bus, so it is safe to unref + * @bus using gst_object_unref() after setting the bus watch. + * * MT safe. * * Returns: The event source id or 0 if @bus already got an event source. @@ -967,9 +1016,12 @@ gst_bus_add_watch_full (GstBus * bus, gint priority, * from @func. If the watch was added to the default main context it is also * possible to remove the watch using g_source_remove(). * - * Returns: The event source id or 0 if @bus already got an event source. + * The bus watch will take its own reference to the @bus, so it is safe to unref + * @bus using gst_object_unref() after setting the bus watch. * * MT safe. + * + * Returns: The event source id or 0 if @bus already got an event source. */ guint gst_bus_add_watch (GstBus * bus, GstBusFunc func, gpointer user_data)