Commit da2e5c6e authored by Jussi Kukkonen's avatar Jussi Kukkonen

Add gupnp_service_info_get_introspection_async_full()

This version of get_introspection can be cancelled using GCancellable.

https://bugzilla.gnome.org/show_bug.cgi?id=704867
parent 64e5b087
......@@ -77,12 +77,18 @@ typedef struct {
GUPnPServiceIntrospectionCallback callback;
gpointer user_data;
GCancellable *cancellable;
gulong cancelled_id;
SoupMessage *message;
} GetSCPDURLData;
static void
get_scpd_url_data_free (GetSCPDURLData *data)
{
if (data->cancellable)
g_object_unref (data->cancellable);
g_slice_free (GetSCPDURLData, data);
}
......@@ -187,6 +193,10 @@ gupnp_service_info_dispose (GObject *object)
data = info->priv->pending_gets->data;
if (data->cancellable)
g_cancellable_disconnect (data->cancellable,
data->cancelled_id);
soup_session_cancel_message (session,
data->message,
SOUP_STATUS_CANCELLED);
......@@ -649,6 +659,12 @@ got_scpd_url (G_GNUC_UNUSED SoupSession *session,
} else
error = _gupnp_error_new_server_error (msg);
/* prevent the callback from canceling the cancellable
* (and so freeing data just before we do) */
if (data->cancellable)
g_cancellable_disconnect (data->cancellable,
data->cancelled_id);
data->info->priv->pending_gets =
g_list_remove (data->info->priv->pending_gets, data);
......@@ -663,6 +679,38 @@ got_scpd_url (G_GNUC_UNUSED SoupSession *session,
get_scpd_url_data_free (data);
}
static void
cancellable_cancelled_cb (GCancellable *cancellable,
gpointer user_data)
{
GUPnPServiceInfo *info;
GetSCPDURLData *data;
SoupSession *session;
GError *error;
data = user_data;
info = data->info;
session = gupnp_context_get_session (info->priv->context);
soup_session_cancel_message (session,
data->message,
SOUP_STATUS_CANCELLED);
info->priv->pending_gets =
g_list_remove (info->priv->pending_gets, data);
error = g_error_new (G_IO_ERROR,
G_IO_ERROR_CANCELLED,
"The call was canceled");
data->callback (data->info,
NULL,
error,
data->user_data);
get_scpd_url_data_free (data);
}
/**
* gupnp_service_info_get_introspection_async:
* @info: A #GUPnPServiceInfo
......@@ -678,6 +726,35 @@ gupnp_service_info_get_introspection_async
(GUPnPServiceInfo *info,
GUPnPServiceIntrospectionCallback callback,
gpointer user_data)
{
gupnp_service_info_get_introspection_async_full (info,
callback,
NULL,
user_data);
}
/**
* gupnp_service_info_get_introspection_async_full:
* @info: A #GUPnPServiceInfo
* @callback: (scope async) : callback to be called when introspection object is ready.
* @cancellable: GCancellable that can be used to cancel the call, or %NULL.
* @user_data: user_data to be passed to the callback.
*
* Note that introspection object is created from the information in service
* description document (SCPD) provided by the service so it can not be created
* if the service does not provide an SCPD.
*
* If @cancellable is used to cancel the call, @callback will be called with
* error code G_IO_ERROR_CANCELLED.
*
* Since: 0.20.10.
**/
void
gupnp_service_info_get_introspection_async_full
(GUPnPServiceInfo *info,
GUPnPServiceIntrospectionCallback callback,
GCancellable *cancellable,
gpointer user_data)
{
GetSCPDURLData *data;
char *scpd_url;
......@@ -729,4 +806,14 @@ gupnp_service_info_get_introspection_async
data->message,
(SoupSessionCallback) got_scpd_url,
data);
data->cancellable = cancellable;
if (data->cancellable) {
g_object_ref (cancellable);
data->cancelled_id = g_cancellable_connect
(data->cancellable,
G_CALLBACK (cancellable_cancelled_cb),
data,
NULL);
}
}
......@@ -133,6 +133,13 @@ gupnp_service_info_get_introspection_async
GUPnPServiceIntrospectionCallback callback,
gpointer user_data);
void
gupnp_service_info_get_introspection_async_full
(GUPnPServiceInfo *info,
GUPnPServiceIntrospectionCallback callback,
GCancellable *cancellable,
gpointer user_data);
G_END_DECLS
#endif /* __GUPNP_SERVICE_INFO_H__ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment