mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
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:
parent
5659831526
commit
1d9cd2a5b3
5 changed files with 102 additions and 179 deletions
12
ChangeLog
12
ChangeLog
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in a new issue