+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>
* gst/playback/gstplaysink.c: (gst_play_sink_set_mute),
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
gst_gio_base_sink_stop (GstBaseSink * base_sink)
{
GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
+ gboolean success;
+ GError *err = NULL;
if (G_IS_OUTPUT_STREAM (sink->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);
sink->stream = NULL;
}
GST_STATE (sink) != GST_STATE_PAUSED));
if (G_IS_OUTPUT_STREAM (sink->stream)) {
+ gboolean success;
+ GError *err = NULL;
+
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);
sink->stream = NULL;
}
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
gst_gio_base_src_stop (GstBaseSrc * base_src)
{
GstGioBaseSrc *src = GST_GIO_BASE_SRC (base_src);
+ gboolean success;
+ GError *err = NULL;
if (G_IS_INPUT_STREAM (src->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);
src->stream = NULL;
}
void
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 ((GST_STATE (src) != GST_STATE_PLAYING &&
GST_STATE (src) != GST_STATE_PAUSED));
if (G_IS_INPUT_STREAM (src->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);
src->stream = NULL;
}
* </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
#include <config.h>
#endif
}
}
-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
gst_gio_sink_start (GstBaseSink * base_sink)
{
stream =
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);
g_object_unref (file);
* </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
#include <config.h>
#endif
}
}
-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
gst_gio_src_start (GstBaseSrc * base_src)
{
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);
if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) {