ext/gio/: Don't use async operations as they require a running main loop.

Original commit message from CVS:
* ext/gio/gstgiobasesink.c: (gst_gio_base_sink_stop),
(gst_gio_base_sink_set_stream):
* ext/gio/gstgiobasesrc.c: (gst_gio_base_src_stop),
(gst_gio_base_src_set_stream):
* ext/gio/gstgiosink.c: (gst_gio_sink_start):
* ext/gio/gstgiosrc.c: (gst_gio_src_start):
Don't use async operations as they require a running main loop.
This makes us block again when closing streams and unable
to mount the enclosing volume of an URI if it isn't yet.
This commit is contained in:
Sebastian Dröge 2008-02-17 05:15:45 +00:00
parent 5659831526
commit 1d9cd2a5b3
5 changed files with 102 additions and 179 deletions

View file

@ -1,3 +1,15 @@
2008-02-17 Sebastian Dröge <slomo@circular-chaos.org>
* ext/gio/gstgiobasesink.c: (gst_gio_base_sink_stop),
(gst_gio_base_sink_set_stream):
* ext/gio/gstgiobasesrc.c: (gst_gio_base_src_stop),
(gst_gio_base_src_set_stream):
* ext/gio/gstgiosink.c: (gst_gio_sink_start):
* ext/gio/gstgiosrc.c: (gst_gio_src_start):
Don't use async operations as they require a running main loop.
This makes us block again when closing streams and unable
to mount the enclosing volume of an URI if it isn't yet.
2008-02-15 Wim Taymans <wim.taymans@collabora.co.uk> 2008-02-15 Wim Taymans <wim.taymans@collabora.co.uk>
* gst/playback/gstplaysink.c: (gst_play_sink_set_mute), * gst/playback/gstplaysink.c: (gst_play_sink_set_mute),

View file

@ -128,39 +128,31 @@ gst_gio_base_sink_start (GstBaseSink * base_sink)
return TRUE; return TRUE;
} }
static void
close_stream_cb (GObject * object, GAsyncResult * res, gpointer user_data)
{
GstGioBaseSink *sink = GST_GIO_BASE_SINK (user_data);
gboolean success;
GError *err = NULL;
success = g_output_stream_close_finish (G_OUTPUT_STREAM (object), res, &err);
if (!success
&& !gst_gio_error (sink, "g_output_stream_close_async", &err, NULL)) {
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_output_stream_close_async failed: %s", err->message));
g_clear_error (&err);
} else if (!success) {
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_output_stream_close_async failed"));
} else {
GST_DEBUG_OBJECT (sink, "g_output_stream_close_async succeeded");
}
g_object_unref (sink);
}
static gboolean static gboolean
gst_gio_base_sink_stop (GstBaseSink * base_sink) gst_gio_base_sink_stop (GstBaseSink * base_sink)
{ {
GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink); GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
gboolean success;
GError *err = NULL;
if (G_IS_OUTPUT_STREAM (sink->stream)) { if (G_IS_OUTPUT_STREAM (sink->stream)) {
GST_DEBUG_OBJECT (sink, "closing stream"); GST_DEBUG_OBJECT (sink, "closing stream");
g_output_stream_close_async (sink->stream, 0, sink->cancel, close_stream_cb,
g_object_ref (sink)); /* FIXME: can block but unfortunately we can't use async operations
* here because they require a running main loop */
success = g_output_stream_close (sink->stream, sink->cancel, &err);
if (!success && !gst_gio_error (sink, "g_output_stream_close", &err, NULL)) {
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_ooutput_stream_close failed: %s", err->message));
g_clear_error (&err);
} else if (!success) {
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_output_stream_close failed"));
} else {
GST_DEBUG_OBJECT (sink, "g_outut_stream_close succeeded");
}
g_object_unref (sink->stream); g_object_unref (sink->stream);
sink->stream = NULL; sink->stream = NULL;
} }
@ -329,9 +321,26 @@ gst_gio_base_sink_set_stream (GstGioBaseSink * sink, GOutputStream * stream)
GST_STATE (sink) != GST_STATE_PAUSED)); GST_STATE (sink) != GST_STATE_PAUSED));
if (G_IS_OUTPUT_STREAM (sink->stream)) { if (G_IS_OUTPUT_STREAM (sink->stream)) {
gboolean success;
GError *err = NULL;
GST_DEBUG_OBJECT (sink, "closing old stream"); GST_DEBUG_OBJECT (sink, "closing old stream");
g_output_stream_close_async (sink->stream, 0, sink->cancel, close_stream_cb,
g_object_ref (sink)); /* FIXME: can block but unfortunately we can't use async operations
* here because they require a running main loop */
success = g_output_stream_close (sink->stream, sink->cancel, &err);
if (!success && !gst_gio_error (sink, "g_output_stream_close", &err, NULL)) {
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_output_stream_close failed: %s", err->message));
g_clear_error (&err);
} else if (!success) {
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_output_stream_close failed"));
} else {
GST_DEBUG_OBJECT (sink, "g_output_stream_close succeeded");
}
g_object_unref (sink->stream); g_object_unref (sink->stream);
sink->stream = NULL; sink->stream = NULL;
} }

View file

@ -128,39 +128,31 @@ gst_gio_base_src_start (GstBaseSrc * base_src)
return TRUE; return TRUE;
} }
static void
close_stream_cb (GObject * object, GAsyncResult * res, gpointer user_data)
{
GstGioBaseSrc *src = GST_GIO_BASE_SRC (user_data);
gboolean success;
GError *err = NULL;
success = g_input_stream_close_finish (G_INPUT_STREAM (object), res, &err);
if (!success
&& !gst_gio_error (src, "g_input_stream_close_async", &err, NULL)) {
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
("g_input_stream_close_async failed: %s", err->message));
g_clear_error (&err);
} else if (!success) {
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
("g_input_stream_close_async failed"));
} else {
GST_DEBUG_OBJECT (src, "g_input_stream_close_async succeeded");
}
g_object_unref (src);
}
static gboolean static gboolean
gst_gio_base_src_stop (GstBaseSrc * base_src) gst_gio_base_src_stop (GstBaseSrc * base_src)
{ {
GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src); GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src);
gboolean success;
GError *err = NULL;
if (G_IS_INPUT_STREAM (src->stream)) { if (G_IS_INPUT_STREAM (src->stream)) {
GST_DEBUG_OBJECT (src, "closing stream"); GST_DEBUG_OBJECT (src, "closing stream");
g_input_stream_close_async (src->stream, 0, src->cancel, close_stream_cb,
g_object_ref (src)); /* FIXME: can block but unfortunately we can't use async operations
* here because they require a running main loop */
success = g_input_stream_close (src->stream, src->cancel, &err);
if (!success && !gst_gio_error (src, "g_input_stream_close", &err, NULL)) {
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
("g_input_stream_close failed: %s", err->message));
g_clear_error (&err);
} else if (!success) {
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
("g_input_stream_close failed"));
} else {
GST_DEBUG_OBJECT (src, "g_input_stream_close succeeded");
}
g_object_unref (src->stream); g_object_unref (src->stream);
src->stream = NULL; src->stream = NULL;
} }
@ -357,14 +349,31 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
void void
gst_gio_base_src_set_stream (GstGioBaseSrc * src, GInputStream * stream) gst_gio_base_src_set_stream (GstGioBaseSrc * src, GInputStream * stream)
{ {
gboolean success;
GError *err = NULL;
g_return_if_fail (G_IS_INPUT_STREAM (stream)); g_return_if_fail (G_IS_INPUT_STREAM (stream));
g_return_if_fail ((GST_STATE (src) != GST_STATE_PLAYING && g_return_if_fail ((GST_STATE (src) != GST_STATE_PLAYING &&
GST_STATE (src) != GST_STATE_PAUSED)); GST_STATE (src) != GST_STATE_PAUSED));
if (G_IS_INPUT_STREAM (src->stream)) { if (G_IS_INPUT_STREAM (src->stream)) {
GST_DEBUG_OBJECT (src, "closing old stream"); GST_DEBUG_OBJECT (src, "closing old stream");
g_input_stream_close_async (src->stream, 0, src->cancel, close_stream_cb,
g_object_ref (src)); /* FIXME: can block but unfortunately we can't use async operations
* here because they require a running main loop */
success = g_input_stream_close (src->stream, src->cancel, &err);
if (!success && !gst_gio_error (src, "g_input_stream_close", &err, NULL)) {
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
("g_input_stream_close failed: %s", err->message));
g_clear_error (&err);
} else if (!success) {
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
("g_input_stream_close failed"));
} else {
GST_DEBUG_OBJECT (src, "g_input_stream_close succeeded");
}
g_object_unref (src->stream); g_object_unref (src->stream);
src->stream = NULL; src->stream = NULL;
} }

View file

@ -58,6 +58,14 @@
* </refsect2> * </refsect2>
*/ */
/* FIXME: We would like to mount the enclosing volume of an URL
* if it isn't mounted yet but this is possible async-only.
* Unfortunately this requires a running main loop from the
* default context and we can't guarantuee this!
*
* We would also like to do authentication while mounting.
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
@ -183,34 +191,6 @@ gst_gio_sink_get_property (GObject * object, guint prop_id,
} }
} }
static void
mount_cb (GObject * source, GAsyncResult * res, gpointer user_data)
{
gboolean success;
GError *err = NULL;
GstGioSink *sink = GST_GIO_SINK (user_data);
success = g_file_mount_enclosing_volume_finish (G_FILE (source), res, &err);
if (!success
&& !gst_gio_error (sink, "g_file_mount_enclosing_volume", &err, NULL)) {
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_file_mount_enclosing_volume failed: %s", err->message));
g_clear_error (&err);
} else if (!success) {
GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_file_mount_enclosing_volume failed"));
} else {
GST_DEBUG ("g_file_mount_enclosing_volume failed succeeded");
}
sink->mount_successful = success;
g_main_loop_quit (sink->loop);
g_object_unref (sink);
}
static gboolean static gboolean
gst_gio_sink_start (GstBaseSink * base_sink) gst_gio_sink_start (GstBaseSink * base_sink)
{ {
@ -238,39 +218,6 @@ gst_gio_sink_start (GstBaseSink * base_sink)
stream = stream =
G_OUTPUT_STREAM (g_file_create (file, G_FILE_CREATE_NONE, cancel, &err)); G_OUTPUT_STREAM (g_file_create (file, G_FILE_CREATE_NONE, cancel, &err));
if (stream == NULL && !gst_gio_error (sink, "g_file_read", &err, NULL) &&
GST_GIO_ERROR_MATCHES (err, NOT_MOUNTED)) {
GST_DEBUG ("Trying to mount enclosing volume for %s\n", sink->location);
g_clear_error (&err);
err = NULL;
sink->loop = g_main_loop_new (NULL, TRUE);
if (!sink->loop) {
GST_ELEMENT_ERROR (sink, LIBRARY, INIT,
(NULL), ("Failed to start GMainLoop"));
} else {
sink->mount_successful = FALSE;
/* TODO: authentication: a GMountOperation property that apps can set
* and properties for user/password/etc that can be used more easily
*/
g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, NULL, cancel,
mount_cb, g_object_ref (sink));
g_main_loop_run (sink->loop);
g_main_loop_unref (sink->loop);
sink->loop = NULL;
if (!sink->mount_successful) {
GST_DEBUG ("Mounting the enclosing volume failed for some reason");
} else {
stream =
G_OUTPUT_STREAM (g_file_create (file, G_FILE_CREATE_NONE, cancel,
&err));
}
}
}
success = (stream != NULL); success = (stream != NULL);
g_object_unref (file); g_object_unref (file);

View file

@ -59,6 +59,14 @@
* </refsect2> * </refsect2>
*/ */
/* FIXME: We would like to mount the enclosing volume of an URL
* if it isn't mounted yet but this is possible async-only.
* Unfortunately this requires a running main loop from the
* default context and we can't guarantuee this!
*
* We would also like to do authentication while mounting.
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
@ -178,34 +186,6 @@ gst_gio_src_get_property (GObject * object, guint prop_id,
} }
} }
static void
mount_cb (GObject * source, GAsyncResult * res, gpointer user_data)
{
gboolean success;
GError *err = NULL;
GstGioSrc *src = GST_GIO_SRC (user_data);
success = g_file_mount_enclosing_volume_finish (G_FILE (source), res, &err);
if (!success
&& !gst_gio_error (src, "g_file_mount_enclosing_volume", &err, NULL)) {
GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL),
("g_file_mount_enclosing_volume failed: %s", err->message));
g_clear_error (&err);
} else if (!success) {
GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
("g_file_mount_enclosing_volume failed"));
} else {
GST_DEBUG ("g_file_mount_enclosing_volume failed succeeded");
}
src->mount_successful = success;
g_main_loop_quit (src->loop);
g_object_unref (src);
}
static gboolean static gboolean
gst_gio_src_start (GstBaseSrc * base_src) gst_gio_src_start (GstBaseSrc * base_src)
{ {
@ -230,40 +210,6 @@ gst_gio_src_start (GstBaseSrc * base_src)
stream = G_INPUT_STREAM (g_file_read (file, cancel, &err)); stream = G_INPUT_STREAM (g_file_read (file, cancel, &err));
if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL) &&
GST_GIO_ERROR_MATCHES (err, NOT_MOUNTED)) {
GST_DEBUG ("Trying to mount enclosing volume for %s\n", src->location);
g_clear_error (&err);
err = NULL;
src->loop = g_main_loop_new (NULL, TRUE);
if (!src->loop) {
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
(NULL), ("Failed to start GMainLoop"));
} else {
src->mount_successful = FALSE;
/* TODO: authentication: a GMountOperation property that apps can set
* and properties for user/password/etc that can be used more easily
*/
g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, NULL, cancel,
mount_cb, g_object_ref (src));
g_main_loop_run (src->loop);
g_main_loop_unref (src->loop);
src->loop = NULL;
if (!src->mount_successful) {
GST_ERROR ("Mounting the enclosing volume failed for some reason");
} else {
stream = G_INPUT_STREAM (g_file_read (file, cancel, &err));
}
}
}
src->mount_successful = FALSE;
g_object_unref (file); g_object_unref (file);
if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) { if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) {