gst/gstbus.c (gst_bus_class_init): Declare our private data structure.

Original commit message from CVS:
2006-02-10  Andy Wingo  <wingo@pobox.com>

* gst/gstbus.c (gst_bus_class_init): Declare our private data
structure.
(gst_bus_init): Cache the location of the private data in the
instance structure.
(gst_bus_enable_sync_message_emission)
(gst_bus_disable_sync_message_emission): Implement new public
functions.
(gst_bus_post): Emit the sync-message signal if the user asked for
it. Fixes #330684.

* gst/gstbus.h (GstBus): Use a padding pointer to cache the
location of the bus-private structuure.
(gst_bus_enable_sync_message_emission)
(gst_bus_disable_sync_message_emission): New public functions.
This commit is contained in:
Andy Wingo 2006-02-10 16:04:59 +00:00
parent e126aa34c3
commit da506847ca
4 changed files with 110 additions and 6 deletions

View file

@ -1,3 +1,20 @@
2006-02-10 Andy Wingo <wingo@pobox.com>
* gst/gstbus.c (gst_bus_class_init): Declare our private data
structure.
(gst_bus_init): Cache the location of the private data in the
instance structure.
(gst_bus_enable_sync_message_emission)
(gst_bus_disable_sync_message_emission): Implement new public
functions.
(gst_bus_post): Emit the sync-message signal if the user asked for
it. Fixes #330684.
* gst/gstbus.h (GstBus): Use a padding pointer to cache the
location of the bus-private structuure.
(gst_bus_enable_sync_message_emission)
(gst_bus_disable_sync_message_emission): New public functions.
2006-02-10 Jan Schmidt <thaytan@mad.scientist.com> 2006-02-10 Jan Schmidt <thaytan@mad.scientist.com>
* docs/pwg/building-boiler.xml: * docs/pwg/building-boiler.xml:

View file

@ -100,6 +100,11 @@ static guint gst_bus_signals[LAST_SIGNAL] = { 0 };
/* the context we wakeup when we posted a message on the bus */ /* the context we wakeup when we posted a message on the bus */
static GMainContext *main_context; static GMainContext *main_context;
struct _GstBusPrivate
{
guint num_sync_message_emitters;
};
GType GType
gst_bus_get_type (void) gst_bus_get_type (void)
{ {
@ -199,6 +204,8 @@ gst_bus_class_init (GstBusClass * klass)
marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE); marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
main_context = g_main_context_default (); main_context = g_main_context_default ();
g_type_class_add_private (klass, sizeof (GstBusPrivate));
} }
static void static void
@ -207,6 +214,8 @@ gst_bus_init (GstBus * bus)
bus->queue = g_queue_new (); bus->queue = g_queue_new ();
bus->queue_lock = g_mutex_new (); bus->queue_lock = g_mutex_new ();
bus->priv = G_TYPE_INSTANCE_GET_PRIVATE (bus, GST_TYPE_BUS, GstBusPrivate);
GST_DEBUG_OBJECT (bus, "created"); GST_DEBUG_OBJECT (bus, "created");
} }
@ -301,6 +310,7 @@ gst_bus_post (GstBus * bus, GstMessage * message)
{ {
GstBusSyncReply reply = GST_BUS_PASS; GstBusSyncReply reply = GST_BUS_PASS;
GstBusSyncHandler handler; GstBusSyncHandler handler;
gboolean emit_sync_message;
gpointer handler_data; gpointer handler_data;
g_return_val_if_fail (GST_IS_BUS (bus), FALSE); g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
@ -316,12 +326,19 @@ gst_bus_post (GstBus * bus, GstMessage * message)
handler = bus->sync_handler; handler = bus->sync_handler;
handler_data = bus->sync_handler_data; handler_data = bus->sync_handler_data;
emit_sync_message = bus->priv->num_sync_message_emitters > 0;
GST_OBJECT_UNLOCK (bus); GST_OBJECT_UNLOCK (bus);
/* first call the sync handler if it is installed */ /* first call the sync handler if it is installed */
if (handler) if (handler)
reply = handler (bus, message, handler_data); reply = handler (bus, message, handler_data);
/* emit sync-message if requested to do so via
gst_bus_enable_sync_message_emission. terrible but effective */
if (emit_sync_message && reply != GST_BUS_DROP
&& handler != gst_bus_sync_signal_handler)
gst_bus_sync_signal_handler (bus, message, NULL);
/* now see what we should do with the message */ /* now see what we should do with the message */
switch (reply) { switch (reply) {
case GST_BUS_DROP: case GST_BUS_DROP:
@ -904,6 +921,71 @@ gst_bus_sync_signal_handler (GstBus * bus, GstMessage * message, gpointer data)
return GST_BUS_PASS; return GST_BUS_PASS;
} }
/**
* gst_bus_enable_sync_message_emission:
* @bus: a #GstBus on which you want to receive the "sync-message" signal
*
* Instructs GStreamer to emit the sync-message signal after running the bus's
* sync handler. This function is here so that code can ensure that they can
* synchronously receive messages without having to affect what the bin's sync
* handler is.
*
* This function may be called multiple times. To clean up, the caller is
* responsible for calling gst_bus_disable_sync_message_emission() as many times
* as this function is called.
*
* While this function looks similar to gst_bus_add_signal_watch(), it is not
* exactly the same -- this function enables <i>synchronous</i> emission of
* signals when messages arrive; gst_bus_add_signal_watch adds an idle callback
* to pop messages off the bus <i>asynchronously</a>. The sync-message signal
* comes from the thread of whatever object posted the message; the message
* signal is marshalled to the main thread via the main loop.
*
* MT safe.
*/
void
gst_bus_enable_sync_message_emission (GstBus * bus)
{
g_return_if_fail (GST_IS_BUS (bus));
GST_OBJECT_LOCK (bus);
bus->priv->num_sync_message_emitters++;
GST_OBJECT_UNLOCK (bus);
}
/**
* gst_bus_disable_sync_message_emission:
* @bus: a #GstBus on which you previously called
* gst_bus_enable_sync_message_emission()
*
* Instructs GStreamer to stop emitting the sync-message signal for this bus.
* See gst_bus_enable_sync_message_emission() for more information.
*
* In the event that multiple pieces of code have called
* gst_bus_enable_sync_message_emission(), the sync-message emissions will only
* be stopped after all calls to gst_bus_enable_sync_message_emission() were
* "cancelled" by calling this function. In this way the semantics are exactly
* the same as gst_object_ref(); that which calls enable should also call
* disable.
*
* MT safe.
*/
void
gst_bus_disable_sync_message_emission (GstBus * bus)
{
g_return_if_fail (GST_IS_BUS (bus));
g_return_if_fail (bus->num_signal_watchers == 0);
GST_OBJECT_LOCK (bus);
bus->priv->num_sync_message_emitters--;
GST_OBJECT_UNLOCK (bus);
}
/** /**
* gst_bus_add_signal_watch_full: * gst_bus_add_signal_watch_full:
* @bus: a #GstBus on which you want to receive the "message" signal * @bus: a #GstBus on which you want to receive the "message" signal

View file

@ -23,6 +23,7 @@
#define __GST_BUS_H__ #define __GST_BUS_H__
typedef struct _GstBus GstBus; typedef struct _GstBus GstBus;
typedef struct _GstBusPrivate GstBusPrivate;
typedef struct _GstBusClass GstBusClass; typedef struct _GstBusClass GstBusClass;
#include <gst/gstmessage.h> #include <gst/gstmessage.h>
@ -121,7 +122,8 @@ struct _GstBus
guint num_signal_watchers; guint num_signal_watchers;
/*< private > */ /*< private > */
gpointer _gst_reserved[GST_PADDING]; GstBusPrivate *priv;
gpointer _gst_reserved[GST_PADDING - 1];
}; };
struct _GstBusClass struct _GstBusClass
@ -176,6 +178,9 @@ void gst_bus_add_signal_watch (GstBus * bus);
void gst_bus_add_signal_watch_full (GstBus * bus, gint priority); void gst_bus_add_signal_watch_full (GstBus * bus, gint priority);
void gst_bus_remove_signal_watch (GstBus * bus); void gst_bus_remove_signal_watch (GstBus * bus);
void gst_bus_enable_sync_message_emission (GstBus * bus);
void gst_bus_disable_sync_message_emission (GstBus * bus);
G_END_DECLS G_END_DECLS
#endif /* __GST_BUS_H__ */ #endif /* __GST_BUS_H__ */

View file

@ -21,7 +21,7 @@
#undef GST_GCOV_ENABLED #undef GST_GCOV_ENABLED
/* Default errorlevel to use */ /* Default errorlevel to use */
#define GST_LEVEL_DEFAULT GST_LEVEL_NONE #define GST_LEVEL_DEFAULT GST_LEVEL_ERROR
/* GStreamer license */ /* GStreamer license */
#define GST_LICENSE "LGPL" #define GST_LICENSE "LGPL"
@ -30,16 +30,16 @@
#define GST_PACKAGE_ORIGIN "Unknown package origin" #define GST_PACKAGE_ORIGIN "Unknown package origin"
/* package name in plugins */ /* package name in plugins */
#define GST_PACKAGE_NAME "GStreamer source release" #define GST_PACKAGE_NAME "GStreamer CVS/prerelease"
/* Define the version */ /* Define the version */
#define GST_VERSION "0.10.3" #define GST_VERSION "0.10.3.1"
/* Define the MAJOR.MINOR version */ /* Define the MAJOR.MINOR version */
#define GST_MAJORMINOR "0.10" #define GST_MAJORMINOR "0.10"
/* Define host CPU */ /* Define host CPU */
#define HOST_CPU "i686" #define HOST_CPU "powerpc"
/* Define if the host CPU is an Alpha */ /* Define if the host CPU is an Alpha */
#undef HAVE_CPU_ALPHA #undef HAVE_CPU_ALPHA
@ -216,7 +216,7 @@
#undef USE_POISONING #undef USE_POISONING
/* Version number of package */ /* Version number of package */
#define VERSION "0.10.3" #define VERSION "0.10.3.1"
/* Define to 1 if your processor stores words with the most significant byte /* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */ first (like Motorola and SPARC, unlike Intel and VAX). */