2 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
4 * gstbus.c: GstBus subsystem
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
24 * @short_description: Asynchronous message bus subsystem
25 * @see_also: #GstMessage, #GstElement
27 * The #GstBus is an object responsible for delivering #GstMessages in
28 * a first-in first-out way from the streaming threads to the application.
30 * Since the application typically only wants to deal with delivery of these
31 * messages from one thread, the GstBus will marshall the messages between
32 * different threads. This is important since the actual streaming of media
33 * is done in another thread than the application.
35 * The GstBus provides support for #GSource based notifications. This makes it
36 * possible to handle the delivery in the glib mainloop.
38 * The #GSource callback function gst_bus_async_signal_func() can be used to
39 * convert all bus messages into signal emissions.
41 * A message is posted on the bus with the gst_bus_post() method. With the
42 * gst_bus_peek() and gst_bus_pop() methods one can look at or retrieve a previously
45 * The bus can be polled with the gst_bus_poll() method. This methods blocks
46 * up to the specified timeout value until one of the specified messages types
47 * is posted on the bus. The application can then _pop() the messages from the
49 * Alternatively the application can register an asynchronous bus function
50 * using gst_bus_add_watch_full() or gst_bus_add_watch(). This function will
51 * receive messages a short while after they have been posted.
53 * It is also possible to get messages from the bus without any thread
54 * marshalling with the gst_bus_set_sync_handler() method. This makes it
55 * possible to react to a message in the same thread that posted the
56 * message on the bus. This should only be used if the application is able
57 * to deal with messages from different threads.
59 * Every #GstPipeline has one bus.
61 * Note that a #GstPipeline will set its bus into flushing state when changing
62 * from READY to NULL state.
64 * Last reviewed on 2005-10-28 (0.9.4)
71 #include <sys/types.h>
73 #include "gst_private.h"
78 #define GST_CAT_DEFAULT GST_CAT_BUS
88 static void gst_bus_class_init (GstBusClass * klass);
89 static void gst_bus_init (GstBus * bus);
90 static void gst_bus_dispose (GObject * object);
92 static void gst_bus_set_property (GObject * object, guint prop_id,
93 const GValue * value, GParamSpec * pspec);
94 static void gst_bus_get_property (GObject * object, guint prop_id,
95 GValue * value, GParamSpec * pspec);
97 static GstObjectClass *parent_class = NULL;
98 static guint gst_bus_signals[LAST_SIGNAL] = { 0 };
100 /* the context we wakeup when we posted a message on the bus */
101 static GMainContext *main_context;
104 gst_bus_get_type (void)
106 static GType bus_type = 0;
109 static const GTypeInfo bus_info = {
110 sizeof (GstBusClass),
113 (GClassInitFunc) gst_bus_class_init,
118 (GInstanceInitFunc) gst_bus_init,
122 bus_type = g_type_register_static (GST_TYPE_OBJECT, "GstBus", &bus_info, 0);
127 /* fixme: do something about this */
129 marshal_VOID__MINIOBJECT (GClosure * closure, GValue * return_value,
130 guint n_param_values, const GValue * param_values, gpointer invocation_hint,
131 gpointer marshal_data)
133 typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1,
135 register marshalfunc_VOID__MINIOBJECT callback;
136 register GCClosure *cc = (GCClosure *) closure;
137 register gpointer data1, data2;
139 g_return_if_fail (n_param_values == 2);
141 if (G_CCLOSURE_SWAP_DATA (closure)) {
142 data1 = closure->data;
143 data2 = g_value_peek_pointer (param_values + 0);
145 data1 = g_value_peek_pointer (param_values + 0);
146 data2 = closure->data;
149 (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data : cc->
152 callback (data1, gst_value_get_mini_object (param_values + 1), data2);
156 gst_bus_class_init (GstBusClass * klass)
158 GObjectClass *gobject_class;
159 GstObjectClass *gstobject_class;
161 gobject_class = (GObjectClass *) klass;
162 gstobject_class = (GstObjectClass *) klass;
164 parent_class = g_type_class_peek_parent (klass);
166 if (!g_thread_supported ())
167 g_thread_init (NULL);
169 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bus_dispose);
170 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bus_set_property);
171 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bus_get_property);
174 * GstBus::sync-message:
175 * @bus: the object which received the signal
176 * @message: the message that has been posted synchronously
178 * A message has been posted on the bus. This signal is emitted from the
179 * thread that posted the message so one has to be carefull with locking.
181 gst_bus_signals[SYNC_MESSAGE] =
182 g_signal_new ("sync-message", G_TYPE_FROM_CLASS (klass),
183 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
184 G_STRUCT_OFFSET (GstBusClass, sync_message), NULL, NULL,
185 marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
189 * @bus: the object which received the signal
190 * @message: the message that has been posted asynchronously
192 * A message has been posted on the bus. This signal is emitted from a
193 * GSource added to the mainloop.
195 gst_bus_signals[ASYNC_MESSAGE] =
196 g_signal_new ("message", G_TYPE_FROM_CLASS (klass),
197 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
198 G_STRUCT_OFFSET (GstBusClass, message), NULL, NULL,
199 marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
201 main_context = g_main_context_default ();
205 gst_bus_init (GstBus * bus)
207 bus->queue = g_queue_new ();
208 bus->queue_lock = g_mutex_new ();
210 GST_DEBUG_OBJECT (bus, "created");
214 gst_bus_dispose (GObject * object)
218 bus = GST_BUS (object);
223 g_mutex_lock (bus->queue_lock);
225 message = g_queue_pop_head (bus->queue);
227 gst_message_unref (message);
228 } while (message != NULL);
229 g_queue_free (bus->queue);
231 g_mutex_unlock (bus->queue_lock);
232 g_mutex_free (bus->queue_lock);
233 bus->queue_lock = NULL;
236 G_OBJECT_CLASS (parent_class)->dispose (object);
240 gst_bus_set_property (GObject * object, guint prop_id,
241 const GValue * value, GParamSpec * pspec)
245 bus = GST_BUS (object);
249 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
255 gst_bus_get_property (GObject * object, guint prop_id,
256 GValue * value, GParamSpec * pspec)
260 bus = GST_BUS (object);
264 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
272 * Creates a new #GstBus instance.
274 * Returns: a new #GstBus instance
281 result = g_object_new (gst_bus_get_type (), NULL);
288 * @bus: a #GstBus to post on
289 * @message: The #GstMessage to post
291 * Post a message on the given bus. Ownership of the message
292 * is taken by the bus.
294 * Returns: TRUE if the message could be posted, FALSE if the bus is flushing.
299 gst_bus_post (GstBus * bus, GstMessage * message)
301 GstBusSyncReply reply = GST_BUS_PASS;
302 GstBusSyncHandler handler;
303 gpointer handler_data;
305 g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
306 g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
308 GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus, type %s",
309 message, gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
312 /* check if the bus is flushing */
313 if (GST_OBJECT_FLAG_IS_SET (bus, GST_BUS_FLUSHING))
316 handler = bus->sync_handler;
317 handler_data = bus->sync_handler_data;
320 /* first call the sync handler if it is installed */
322 reply = handler (bus, message, handler_data);
324 /* now see what we should do with the message */
327 /* drop the message */
328 GST_DEBUG_OBJECT (bus, "[msg %p] dropped", message);
331 /* pass the message to the async queue, refcount passed in the queue */
332 GST_DEBUG_OBJECT (bus, "[msg %p] pushing on async queue", message);
333 g_mutex_lock (bus->queue_lock);
334 g_queue_push_tail (bus->queue, message);
335 g_mutex_unlock (bus->queue_lock);
336 GST_DEBUG_OBJECT (bus, "[msg %p] pushed on async queue", message);
338 /* FIXME cannot assume sources are only in the default context */
339 g_main_context_wakeup (main_context);
344 /* async delivery, we need a mutex and a cond to block
346 GMutex *lock = g_mutex_new ();
347 GCond *cond = g_cond_new ();
349 GST_MESSAGE_COND (message) = cond;
350 GST_MESSAGE_GET_LOCK (message) = lock;
352 GST_DEBUG_OBJECT (bus, "[msg %p] waiting for async delivery", message);
354 /* now we lock the message mutex, send the message to the async
355 * queue. When the message is handled by the app and destroyed,
356 * the cond will be signalled and we can continue */
358 g_mutex_lock (bus->queue_lock);
359 g_queue_push_tail (bus->queue, message);
360 g_mutex_unlock (bus->queue_lock);
362 /* FIXME cannot assume sources are only in the default context */
363 g_main_context_wakeup (main_context);
365 /* now block till the message is freed */
366 g_cond_wait (cond, lock);
367 g_mutex_unlock (lock);
369 GST_DEBUG_OBJECT (bus, "[msg %p] delivered asynchronously", message);
376 g_warning ("invalid return from bus sync handler");
384 GST_DEBUG_OBJECT (bus, "bus is flushing");
385 gst_message_unref (message);
393 * gst_bus_have_pending:
394 * @bus: a #GstBus to check
396 * Check if there are pending messages on the bus that
399 * Returns: TRUE if there are messages on the bus to be handled, FALSE
405 gst_bus_have_pending (GstBus * bus)
409 g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
411 g_mutex_lock (bus->queue_lock);
412 /* see if there is a message on the bus */
413 result = !g_queue_is_empty (bus->queue);
414 g_mutex_unlock (bus->queue_lock);
420 * gst_bus_set_flushing:
422 * @flushing: whether or not to flush the bus
424 * If @flushing, flush out and unref any messages queued in the bus. Releases
425 * references to the message origin objects. Will flush future messages until
426 * gst_bus_set_flushing() sets @flushing to #FALSE.
431 gst_bus_set_flushing (GstBus * bus, gboolean flushing)
438 GST_OBJECT_FLAG_SET (bus, GST_BUS_FLUSHING);
440 GST_DEBUG_OBJECT (bus, "set bus flushing");
442 while ((message = gst_bus_pop (bus)))
443 gst_message_unref (message);
445 GST_DEBUG_OBJECT (bus, "unset bus flushing");
446 GST_OBJECT_FLAG_UNSET (bus, GST_BUS_FLUSHING);
455 * @bus: a #GstBus to pop
457 * Get a message from the bus.
459 * Returns: The #GstMessage that is on the bus, or NULL if the bus is empty.
464 gst_bus_pop (GstBus * bus)
468 g_return_val_if_fail (GST_IS_BUS (bus), NULL);
470 g_mutex_lock (bus->queue_lock);
471 message = g_queue_pop_head (bus->queue);
473 GST_DEBUG_OBJECT (bus, "pop from bus, have %d messages, got message %p, %s",
474 g_queue_get_length (bus->queue) + 1, message,
475 gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
477 GST_DEBUG_OBJECT (bus, "pop from bus, no messages");
478 g_mutex_unlock (bus->queue_lock);
487 * Peek the message on the top of the bus' queue. The message will remain
488 * on the bus' message queue. A reference is returned, and needs to be unreffed
491 * Returns: The #GstMessage that is on the bus, or NULL if the bus is empty.
496 gst_bus_peek (GstBus * bus)
500 g_return_val_if_fail (GST_IS_BUS (bus), NULL);
502 g_mutex_lock (bus->queue_lock);
503 message = g_queue_peek_head (bus->queue);
505 gst_message_ref (message);
506 g_mutex_unlock (bus->queue_lock);
508 GST_DEBUG_OBJECT (bus, "peek on bus, got message %p", message);
514 * gst_bus_set_sync_handler:
515 * @bus: a #GstBus to install the handler on
516 * @func: The handler function to install
517 * @data: User data that will be sent to the handler function.
519 * Sets the synchronous handler on the bus. The function will be called
520 * every time a new message is posted on the bus. Note that the function
521 * will be called in the same thread context as the posting object. This
522 * function is usually only called by the creator of the bus. Applications
523 * should handle messages asynchronously using the gst_bus watch and poll
526 * You cannot replace an existing sync_handler. You can pass NULL to this
527 * function, which will clear the existing handler.
530 gst_bus_set_sync_handler (GstBus * bus, GstBusSyncHandler func, gpointer data)
532 g_return_if_fail (GST_IS_BUS (bus));
536 /* Assert if the user attempts to replace an existing sync_handler,
537 * other than to clear it */
538 if (func != NULL && bus->sync_handler != NULL)
541 bus->sync_handler = func;
542 bus->sync_handler_data = data;
550 g_warning ("cannot replace existing sync handler");
555 /* GSource for the bus
564 gst_bus_source_prepare (GSource * source, gint * timeout)
566 GstBusSource *bsrc = (GstBusSource *) source;
569 return gst_bus_have_pending (bsrc->bus);
573 gst_bus_source_check (GSource * source)
575 GstBusSource *bsrc = (GstBusSource *) source;
577 return gst_bus_have_pending (bsrc->bus);
581 gst_bus_source_dispatch (GSource * source, GSourceFunc callback,
584 GstBusFunc handler = (GstBusFunc) callback;
585 GstBusSource *bsource = (GstBusSource *) source;
590 g_return_val_if_fail (bsource != NULL, FALSE);
594 g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
596 message = gst_bus_pop (bus);
597 g_return_val_if_fail (message != NULL, FALSE);
602 GST_DEBUG_OBJECT (bus, "source %p calling dispatch with %p", source, message);
604 keep = handler (bus, message, user_data);
605 gst_message_unref (message);
607 GST_DEBUG_OBJECT (bus, "source %p handler returns %d", source, keep);
613 g_warning ("GstBus watch dispatched without callback\n"
614 "You must call g_source_connect().");
615 gst_message_unref (message);
621 gst_bus_source_finalize (GSource * source)
623 GstBusSource *bsource = (GstBusSource *) source;
625 gst_object_unref (bsource->bus);
629 static GSourceFuncs gst_bus_source_funcs = {
630 gst_bus_source_prepare,
631 gst_bus_source_check,
632 gst_bus_source_dispatch,
633 gst_bus_source_finalize
637 * gst_bus_create_watch:
638 * @bus: a #GstBus to create the watch for
640 * Create watch for this bus. The GSource will be dispatched whenever
641 * a message is on the bus. After the GSource is dispatched, the
642 * message is popped off the bus and unreffed.
644 * Returns: A #GSource that can be added to a mainloop.
647 gst_bus_create_watch (GstBus * bus)
649 GstBusSource *source;
651 g_return_val_if_fail (GST_IS_BUS (bus), NULL);
653 source = (GstBusSource *) g_source_new (&gst_bus_source_funcs,
654 sizeof (GstBusSource));
655 gst_object_ref (bus);
658 return (GSource *) source;
662 * gst_bus_add_watch_full:
663 * @bus: a #GstBus to create the watch for.
664 * @priority: The priority of the watch.
665 * @func: A function to call when a message is received.
666 * @user_data: user data passed to @func.
667 * @notify: the function to call when the source is removed.
669 * Adds a bus watch to the default main context with the given priority.
670 * If the func returns FALSE, the source will be removed.
672 * When the func is called, the message belongs to the caller; if you want to
673 * keep a copy of it, call gst_message_ref() before leaving the func.
675 * The watch can be removed using #g_source_remove().
677 * Returns: The event source id.
682 gst_bus_add_watch_full (GstBus * bus, gint priority,
683 GstBusFunc func, gpointer user_data, GDestroyNotify notify)
688 g_return_val_if_fail (GST_IS_BUS (bus), 0);
690 source = gst_bus_create_watch (bus);
692 if (priority != G_PRIORITY_DEFAULT)
693 g_source_set_priority (source, priority);
695 g_source_set_callback (source, (GSourceFunc) func, user_data, notify);
697 id = g_source_attach (source, NULL);
698 g_source_unref (source);
700 GST_DEBUG_OBJECT (bus, "New source %p", source);
706 * @bus: a #GstBus to create the watch for
707 * @func: A function to call when a message is received.
708 * @user_data: user data passed to @func.
710 * Adds a bus watch to the default main context with the default priority.
712 * The watch can be removed using #g_source_remove().
714 * Returns: The event source id.
719 gst_bus_add_watch (GstBus * bus, GstBusFunc func, gpointer user_data)
721 return gst_bus_add_watch_full (bus, G_PRIORITY_DEFAULT, func,
729 gboolean source_running;
730 GstMessageType events;
735 poll_func (GstBus * bus, GstMessage * message, GstBusPollData * poll_data)
737 if (!g_main_loop_is_running (poll_data->loop)) {
738 GST_DEBUG ("mainloop %p not running", poll_data->loop);
742 if (GST_MESSAGE_TYPE (message) & poll_data->events) {
743 g_return_if_fail (poll_data->message == NULL);
744 /* keep ref to message */
745 poll_data->message = gst_message_ref (message);
746 GST_DEBUG ("mainloop %p quit", poll_data->loop);
747 g_main_loop_quit (poll_data->loop);
752 poll_timeout (GstBusPollData * poll_data)
754 GST_DEBUG ("mainloop %p quit", poll_data->loop);
755 g_main_loop_quit (poll_data->loop);
757 /* we don't remove the GSource as this would free our poll_data,
758 * which we still need */
763 poll_destroy (GstBusPollData * poll_data, gpointer unused)
765 poll_data->source_running = FALSE;
766 if (!poll_data->timeout_id) {
767 g_main_loop_unref (poll_data->loop);
773 poll_destroy_timeout (GstBusPollData * poll_data)
775 poll_data->timeout_id = 0;
776 if (!poll_data->source_running) {
777 g_main_loop_unref (poll_data->loop);
785 * @events: a mask of #GstMessageType, representing the set of message types to
787 * @timeout: the poll timeout, as a #GstClockTimeDiff, or -1 to poll indefinitely.
789 * Poll the bus for messages. Will block while waiting for messages to come.
790 * You can specify a maximum time to poll with the @timeout parameter. If
791 * @timeout is negative, this function will block indefinitely.
793 * All messages not in @events will be popped off the bus and will be ignored.
795 * Because poll is implemented using the "message" signal enabled by
796 * gst_bus_add_signal_watch(), calling gst_bus_poll() will cause the "message"
797 * signal to be emitted for every message that poll sees. Thus a "message"
798 * signal handler will see the same messages that this function sees -- neither
799 * will steal messages from the other.
801 * This function will run a main loop from the default main context when
804 * Returns: The message that was received, or NULL if the poll timed out.
805 * The message is taken from the bus and needs to be unreffed after usage.
808 gst_bus_poll (GstBus * bus, GstMessageType events, GstClockTimeDiff timeout)
810 GstBusPollData *poll_data;
814 poll_data = g_new0 (GstBusPollData, 1);
815 poll_data->source_running = TRUE;
816 poll_data->loop = g_main_loop_new (NULL, FALSE);
817 poll_data->events = events;
818 poll_data->message = NULL;
821 poll_data->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE,
822 timeout / GST_MSECOND, (GSourceFunc) poll_timeout, poll_data,
823 (GDestroyNotify) poll_destroy_timeout);
825 poll_data->timeout_id = 0;
827 id = g_signal_connect_data (bus, "message", G_CALLBACK (poll_func), poll_data,
828 (GClosureNotify) poll_destroy, 0);
830 /* these can be nested, so it's ok */
831 gst_bus_add_signal_watch (bus);
833 GST_DEBUG ("running mainloop %p", poll_data->loop);
834 g_main_loop_run (poll_data->loop);
835 GST_DEBUG ("mainloop stopped %p", poll_data->loop);
837 gst_bus_remove_signal_watch (bus);
840 ret = poll_data->message;
842 if (poll_data->timeout_id)
843 g_source_remove (poll_data->timeout_id);
845 /* poll_data will be freed now */
846 g_signal_handler_disconnect (bus, id);
848 GST_DEBUG_OBJECT (bus, "finished poll with message %p", ret);
854 * gst_bus_async_signal_func:
856 * @message: the #GstMessage received
859 * A helper GstBusFunc that can be used to convert all asynchronous messages
865 gst_bus_async_signal_func (GstBus * bus, GstMessage * message, gpointer data)
869 g_return_val_if_fail (GST_IS_BUS (bus), TRUE);
870 g_return_val_if_fail (message != NULL, TRUE);
872 detail = gst_message_type_to_quark (GST_MESSAGE_TYPE (message));
874 g_signal_emit (bus, gst_bus_signals[ASYNC_MESSAGE], detail, message);
876 /* we never remove this source based on signal emission return values */
881 * gst_bus_sync_signal_handler:
883 * @message: the #GstMessage received
886 * A helper GstBusSyncHandler that can be used to convert all synchronous
887 * messages into signals.
889 * Returns: GST_BUS_PASS
892 gst_bus_sync_signal_handler (GstBus * bus, GstMessage * message, gpointer data)
896 g_return_val_if_fail (GST_IS_BUS (bus), GST_BUS_DROP);
897 g_return_val_if_fail (message != NULL, GST_BUS_DROP);
899 detail = gst_message_type_to_quark (GST_MESSAGE_TYPE (message));
901 g_signal_emit (bus, gst_bus_signals[SYNC_MESSAGE], detail, message);
907 * gst_bus_add_signal_watch:
908 * @bus: a #GstBus on which you want to recieve the "message" signal
910 * Adds a bus signal watch to the default main context with the default priority.
911 * After calling this statement, the bus will emit the message signal for each
912 * message posted on the bus.
914 * This function may be called multiple times. To clean up, the caller is
915 * responsible for calling gst_bus_remove_signal_watch() as many times as this
916 * function is called.
921 gst_bus_add_signal_watch (GstBus * bus)
923 g_return_if_fail (GST_IS_BUS (bus));
925 /* I know the callees don't take this lock, so go ahead and abuse it */
928 if (bus->num_signal_watchers > 0)
931 g_assert (bus->signal_watch_id == 0);
933 bus->signal_watch_id =
934 gst_bus_add_watch (bus, gst_bus_async_signal_func, NULL);
938 bus->num_signal_watchers++;
944 * gst_bus_remove_signal_watch:
945 * @bus: a #GstBus you previously added a signal watch to
947 * Removes a signal watch previously added with gst_bus_add_signal_watch().
952 gst_bus_remove_signal_watch (GstBus * bus)
954 g_return_if_fail (GST_IS_BUS (bus));
956 /* I know the callees don't take this lock, so go ahead and abuse it */
959 if (bus->num_signal_watchers == 0)
962 bus->num_signal_watchers--;
964 if (bus->num_signal_watchers > 0)
967 g_source_remove (bus->signal_watch_id);
968 bus->signal_watch_id = 0;
976 g_critical ("Bus %s has no signal watches attached", GST_OBJECT_NAME (bus));