When downloading and cancelling quickly the uridownloader object and the
element using it could miss the cancelled window and the uridownloader
would fetch the wrong URI and block on subsequent fetches.
This was also problematic when stopping elements, while one task would
call the cancel, another element thread could issue a new fetch_uri. As
the cancel state isn't 'permanent' this fetch_uri would block and
prevent the whole element from stopping and going to NULL.
This patch makes the 'cancelled' state permanent until a
gst_uri_downloader_reset is called. This way the element knows the
window where the uridownloader isn't active and only reactivate it when
ready.
GstFragment *download;
GMutex lock;
GCond cond;
GstFragment *download;
GMutex lock;
GCond cond;
};
static void gst_uri_downloader_finalize (GObject * object);
};
static void gst_uri_downloader_finalize (GObject * object);
+void
+gst_uri_downloader_reset (GstUriDownloader * downloader)
+{
+ g_return_if_fail (downloader != NULL);
+
+ GST_OBJECT_LOCK (downloader);
+ downloader->priv->cancelled = FALSE;
+ GST_OBJECT_UNLOCK (downloader);
+}
+
void
gst_uri_downloader_cancel (GstUriDownloader * downloader)
{
void
gst_uri_downloader_cancel (GstUriDownloader * downloader)
{
GST_DEBUG_OBJECT (downloader, "Cancelling download");
g_object_unref (downloader->priv->download);
downloader->priv->download = NULL;
GST_DEBUG_OBJECT (downloader, "Cancelling download");
g_object_unref (downloader->priv->download);
downloader->priv->download = NULL;
+ downloader->priv->cancelled = TRUE;
GST_OBJECT_UNLOCK (downloader);
GST_DEBUG_OBJECT (downloader, "Signaling chain funtion");
g_mutex_lock (&downloader->priv->lock);
g_cond_signal (&downloader->priv->cond);
g_mutex_unlock (&downloader->priv->lock);
} else {
GST_OBJECT_UNLOCK (downloader);
GST_DEBUG_OBJECT (downloader, "Signaling chain funtion");
g_mutex_lock (&downloader->priv->lock);
g_cond_signal (&downloader->priv->cond);
g_mutex_unlock (&downloader->priv->lock);
} else {
+ gboolean cancelled;
+
+ cancelled = downloader->priv->cancelled;
+ downloader->priv->cancelled = TRUE;
GST_OBJECT_UNLOCK (downloader);
GST_OBJECT_UNLOCK (downloader);
- GST_DEBUG_OBJECT (downloader,
- "Trying to cancell a download that was alredy cancelled");
+ if (cancelled)
+ GST_DEBUG_OBJECT (downloader,
+ "Trying to cancell a download that was alredy cancelled");
g_mutex_lock (&downloader->priv->lock);
g_mutex_lock (&downloader->priv->lock);
+ if (downloader->priv->cancelled) {
+ goto quit;
+ }
+
if (!gst_uri_downloader_set_uri (downloader, uri)) {
goto quit;
}
if (!gst_uri_downloader_set_uri (downloader, uri)) {
goto quit;
}
* - the download failed (Error message on the fetcher bus)
* - the download was canceled
*/
* - the download failed (Error message on the fetcher bus)
* - the download was canceled
*/
- GST_DEBUG_OBJECT (downloader, "Waiting to fetch the URI");
+ GST_DEBUG_OBJECT (downloader, "Waiting to fetch the URI %s", uri);
g_cond_wait (&downloader->priv->cond, &downloader->priv->lock);
g_cond_wait (&downloader->priv->cond, &downloader->priv->lock);
+ if (downloader->priv->cancelled) {
+ if (downloader->priv->download) {
+ g_object_unref (downloader->priv->download);
+ downloader->priv->download = NULL;
+ }
+ goto quit;
+ }
+
GST_OBJECT_LOCK (downloader);
download = downloader->priv->download;
downloader->priv->download = NULL;
GST_OBJECT_LOCK (downloader);
download = downloader->priv->download;
downloader->priv->download = NULL;
GstUriDownloader * gst_uri_downloader_new (void);
GstFragment * gst_uri_downloader_fetch_uri (GstUriDownloader * downloader, const gchar * uri);
GstUriDownloader * gst_uri_downloader_new (void);
GstFragment * gst_uri_downloader_fetch_uri (GstUriDownloader * downloader, const gchar * uri);
+void gst_uri_downloader_reset (GstUriDownloader *downloader);
void gst_uri_downloader_cancel (GstUriDownloader *downloader);
void gst_uri_downloader_free (GstUriDownloader *downloader);
void gst_uri_downloader_cancel (GstUriDownloader *downloader);
void gst_uri_downloader_free (GstUriDownloader *downloader);