mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-04 14:38:48 +00:00
nice: resolve result should go to nice helper thread
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5921>
This commit is contained in:
parent
3972736f91
commit
ebc51e3253
1 changed files with 131 additions and 90 deletions
|
@ -96,7 +96,9 @@ _gst_nice_thread (GstWebRTCNice * ice)
|
||||||
g_main_context_invoke (ice->priv->main_context,
|
g_main_context_invoke (ice->priv->main_context,
|
||||||
(GSourceFunc) _unlock_pc_thread, &ice->priv->lock);
|
(GSourceFunc) _unlock_pc_thread, &ice->priv->lock);
|
||||||
|
|
||||||
|
g_main_context_push_thread_default (ice->priv->main_context);
|
||||||
g_main_loop_run (ice->priv->loop);
|
g_main_loop_run (ice->priv->loop);
|
||||||
|
g_main_context_pop_thread_default (ice->priv->main_context);
|
||||||
|
|
||||||
g_mutex_lock (&ice->priv->lock);
|
g_mutex_lock (&ice->priv->lock);
|
||||||
g_main_context_unref (ice->priv->main_context);
|
g_main_context_unref (ice->priv->main_context);
|
||||||
|
@ -271,125 +273,153 @@ _parse_userinfo (const gchar * userinfo, gchar ** user, gchar ** pass)
|
||||||
*pass = g_uri_unescape_string (&colon[1], NULL);
|
*pass = g_uri_unescape_string (&colon[1], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef void (*GstResolvedCallback)
|
||||||
|
(GstWebRTCNice * nice, GList * addresses, GError * error, gpointer user_data);
|
||||||
|
|
||||||
struct resolve_host_data
|
struct resolve_host_data
|
||||||
{
|
{
|
||||||
GstWebRTCNice *ice;
|
GWeakRef nice_weak;
|
||||||
char *host;
|
char *host;
|
||||||
gboolean main_context_handled;
|
gboolean main_context_handled;
|
||||||
|
GstResolvedCallback resolved_callback;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
GDestroyNotify notify;
|
GDestroyNotify notify;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static struct resolve_host_data *
|
||||||
on_resolve_host (GResolver * resolver, GAsyncResult * res, gpointer user_data)
|
resolve_host_data_new (GstWebRTCNice * ice, const char *host)
|
||||||
{
|
{
|
||||||
GTask *task = user_data;
|
struct resolve_host_data *rh =
|
||||||
struct resolve_host_data *rh;
|
g_atomic_rc_box_new0 (struct resolve_host_data);
|
||||||
GError *error = NULL;
|
|
||||||
GList *addresses;
|
|
||||||
|
|
||||||
rh = g_task_get_task_data (task);
|
g_weak_ref_init (&rh->nice_weak, ice);
|
||||||
|
rh->host = g_strdup (host);
|
||||||
|
|
||||||
if (!(addresses = g_resolver_lookup_by_name_finish (resolver, res, &error))) {
|
return rh;
|
||||||
GST_ERROR ("failed to resolve: %s", error->message);
|
}
|
||||||
g_task_return_error (task, error);
|
|
||||||
g_object_unref (task);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rh->ice, "Resolved %d addresses for host %s with data %p",
|
static struct resolve_host_data *
|
||||||
g_list_length (addresses), rh->host, rh);
|
resolve_host_data_ref (struct resolve_host_data *rh)
|
||||||
|
{
|
||||||
g_task_return_pointer (task, addresses,
|
return (struct resolve_host_data *) g_atomic_rc_box_acquire (rh);
|
||||||
(GDestroyNotify) g_resolver_free_addresses);
|
|
||||||
g_object_unref (task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_resolve_host_data (struct resolve_host_data *rh)
|
resolve_host_data_clear (struct resolve_host_data *rh)
|
||||||
{
|
{
|
||||||
GST_TRACE_OBJECT (rh->ice, "Freeing data %p for resolving host %s", rh,
|
GST_TRACE ("Freeing data %p for resolving host %s", rh, rh->host);
|
||||||
rh->host);
|
|
||||||
|
|
||||||
if (rh->notify)
|
if (rh->notify)
|
||||||
rh->notify (rh->user_data);
|
rh->notify (rh->user_data);
|
||||||
|
|
||||||
|
g_weak_ref_clear (&rh->nice_weak);
|
||||||
g_free (rh->host);
|
g_free (rh->host);
|
||||||
g_free (rh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resolve_host_data *
|
static void
|
||||||
resolve_host_data_new (GstWebRTCNice * ice, const char *host)
|
resolve_host_data_unref (struct resolve_host_data *rh)
|
||||||
{
|
{
|
||||||
struct resolve_host_data *rh = g_new0 (struct resolve_host_data, 1);
|
g_atomic_rc_box_release_full (rh, (GDestroyNotify) resolve_host_data_clear);
|
||||||
|
}
|
||||||
|
|
||||||
rh->ice = ice;
|
static void
|
||||||
rh->host = g_strdup (host);
|
on_resolve_host (GResolver * resolver, GAsyncResult * res, gpointer user_data)
|
||||||
|
{
|
||||||
|
struct resolve_host_data *rh = user_data;
|
||||||
|
GstWebRTCNice *nice = g_weak_ref_get (&rh->nice_weak);
|
||||||
|
GError *error = NULL;
|
||||||
|
GList *addresses;
|
||||||
|
|
||||||
return rh;
|
if (!nice) {
|
||||||
|
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled");
|
||||||
|
rh->resolved_callback (NULL, NULL, error, rh->user_data);
|
||||||
|
resolve_host_data_unref (rh);
|
||||||
|
g_error_free (error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(addresses = g_resolver_lookup_by_name_finish (resolver, res, &error))) {
|
||||||
|
GST_ERROR ("failed to resolve: %s", error->message);
|
||||||
|
|
||||||
|
rh->resolved_callback (nice, NULL, error, rh->user_data);
|
||||||
|
gst_object_unref (nice);
|
||||||
|
resolve_host_data_unref (rh);
|
||||||
|
g_error_free (error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (nice, "Resolved %d addresses for host %s with data %p",
|
||||||
|
g_list_length (addresses), rh->host, rh);
|
||||||
|
|
||||||
|
rh->resolved_callback (nice, addresses, error, rh->user_data);
|
||||||
|
gst_object_unref (nice);
|
||||||
|
resolve_host_data_unref (rh);
|
||||||
|
g_resolver_free_addresses (addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
resolve_host_main_cb (gpointer user_data)
|
resolve_host_main_cb (gpointer user_data)
|
||||||
{
|
{
|
||||||
GResolver *resolver = g_resolver_get_default ();
|
GResolver *resolver = g_resolver_get_default ();
|
||||||
GTask *task = user_data;
|
struct resolve_host_data *rh = user_data;
|
||||||
struct resolve_host_data *rh;
|
GstWebRTCNice *nice = g_weak_ref_get (&rh->nice_weak);
|
||||||
|
|
||||||
rh = g_task_get_task_data (task);
|
if (nice) {
|
||||||
/* no need to error anymore if the main context disappears and this task is
|
/* no need to error anymore if the main context disappears and this task is
|
||||||
* not run */
|
* not run */
|
||||||
rh->main_context_handled = TRUE;
|
rh->main_context_handled = TRUE;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rh->ice, "Resolving host %s", rh->host);
|
GST_DEBUG_OBJECT (nice, "Resolving host %s", rh->host);
|
||||||
g_resolver_lookup_by_name_async (resolver, rh->host, NULL,
|
g_resolver_lookup_by_name_async (resolver, rh->host, NULL,
|
||||||
(GAsyncReadyCallback) on_resolve_host, g_object_ref (task));
|
(GAsyncReadyCallback) on_resolve_host, resolve_host_data_ref (rh));
|
||||||
|
gst_object_unref (nice);
|
||||||
|
}
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
error_task_if_unhandled (GTask * task)
|
error_resolve_if_unhandled (struct resolve_host_data *rh)
|
||||||
{
|
{
|
||||||
struct resolve_host_data *rh;
|
GstWebRTCNice *nice = g_weak_ref_get (&rh->nice_weak);
|
||||||
|
|
||||||
rh = g_task_get_task_data (task);
|
|
||||||
|
|
||||||
if (!rh->main_context_handled) {
|
if (!rh->main_context_handled) {
|
||||||
GST_DEBUG_OBJECT (rh->ice, "host resolve for %s with data %p was never "
|
if (nice) {
|
||||||
|
GST_DEBUG_OBJECT (nice, "host resolve for %s with data %p was never "
|
||||||
|
"executed, main context quit?", rh->host, rh);
|
||||||
|
} else {
|
||||||
|
GST_DEBUG ("host resolve for %s with data %p was never "
|
||||||
"executed, main context quit?", rh->host, rh);
|
"executed, main context quit?", rh->host, rh);
|
||||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "%s",
|
|
||||||
"Cancelled");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (task);
|
GError *error =
|
||||||
|
g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled");
|
||||||
|
rh->resolved_callback (nice, NULL, error, rh->user_data);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nice)
|
||||||
|
gst_object_unref (nice);
|
||||||
|
resolve_host_data_unref (rh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resolve_host_async (GstWebRTCNice * ice, const gchar * host,
|
resolve_host_async (GstWebRTCNice * nice, const gchar * host,
|
||||||
GAsyncReadyCallback cb, gpointer user_data, GDestroyNotify notify)
|
GstResolvedCallback resolved_callback, gpointer user_data,
|
||||||
|
GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
struct resolve_host_data *rh = resolve_host_data_new (ice, host);
|
struct resolve_host_data *rh = resolve_host_data_new (nice, host);
|
||||||
GTask *task;
|
|
||||||
|
|
||||||
|
rh->resolved_callback = resolved_callback;
|
||||||
rh->user_data = user_data;
|
rh->user_data = user_data;
|
||||||
rh->notify = notify;
|
rh->notify = notify;
|
||||||
task = g_task_new (rh->ice, NULL, cb, user_data);
|
|
||||||
|
|
||||||
g_task_set_task_data (task, rh, (GDestroyNotify) free_resolve_host_data);
|
GST_TRACE_OBJECT (nice, "invoking main context for resolving host %s "
|
||||||
|
|
||||||
GST_TRACE_OBJECT (rh->ice, "invoking main context for resolving host %s "
|
|
||||||
"with data %p", host, rh);
|
"with data %p", host, rh);
|
||||||
g_main_context_invoke_full (ice->priv->main_context, G_PRIORITY_DEFAULT,
|
g_main_context_invoke_full (nice->priv->main_context, G_PRIORITY_DEFAULT,
|
||||||
resolve_host_main_cb, task, (GDestroyNotify) error_task_if_unhandled);
|
resolve_host_main_cb, rh, (GDestroyNotify) error_resolve_if_unhandled);
|
||||||
}
|
|
||||||
|
|
||||||
static GList *
|
|
||||||
resolve_host_finish (GstWebRTCNice * ice, GAsyncResult * res, GError ** error)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (g_task_is_valid (res, ice), NULL);
|
|
||||||
|
|
||||||
return g_task_propagate_pointer (G_TASK (res), error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -734,33 +764,38 @@ add_ice_candidate_to_libnice (GstWebRTCICE * ice, guint nice_stream_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_candidate_resolved (GstWebRTCICE * ice, GAsyncResult * res,
|
on_candidate_resolved (GstWebRTCNice * nice, GList * addresses,
|
||||||
gpointer user_data)
|
GError * error, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct resolve_candidate_data *rc = user_data;
|
struct resolve_candidate_data *rc = user_data;
|
||||||
GError *error = NULL;
|
|
||||||
GList *addresses;
|
|
||||||
char *new_candv[4] = { NULL, };
|
char *new_candv[4] = { NULL, };
|
||||||
char *new_addr, *new_candidate;
|
char *new_addr, *new_candidate;
|
||||||
NiceCandidate *cand;
|
NiceCandidate *cand;
|
||||||
GstWebRTCNice *nice = GST_WEBRTC_NICE (ice);
|
|
||||||
|
|
||||||
if (!(addresses = resolve_host_finish (nice, res, &error))) {
|
if (!nice)
|
||||||
|
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled");
|
||||||
|
|
||||||
|
if (error) {
|
||||||
if (rc->promise) {
|
if (rc->promise) {
|
||||||
GstStructure *s = gst_structure_new ("application/x-gst-promise", "error",
|
GstStructure *s = gst_structure_new ("application/x-gst-promise", "error",
|
||||||
G_TYPE_ERROR, error, NULL);
|
G_TYPE_ERROR, error, NULL);
|
||||||
gst_promise_reply (rc->promise, s);
|
gst_promise_reply (rc->promise, s);
|
||||||
} else {
|
} else if (nice) {
|
||||||
GST_WARNING_OBJECT (ice, "Could not resolve candidate address: %s",
|
GST_WARNING_OBJECT (nice, "Could not resolve candidate address: %s",
|
||||||
error->message);
|
error->message);
|
||||||
|
} else {
|
||||||
|
GST_WARNING ("Could not resolve candidate address: %s", error->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!nice)
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GstWebRTCICE *ice = GST_WEBRTC_ICE (nice);
|
||||||
|
|
||||||
new_addr = g_inet_address_to_string (addresses->data);
|
new_addr = g_inet_address_to_string (addresses->data);
|
||||||
g_resolver_free_addresses (addresses);
|
|
||||||
addresses = NULL;
|
|
||||||
|
|
||||||
new_candv[0] = rc->prefix;
|
new_candv[0] = rc->prefix;
|
||||||
new_candv[1] = new_addr;
|
new_candv[1] = new_addr;
|
||||||
|
@ -863,7 +898,7 @@ gst_webrtc_nice_add_candidate (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
|
||||||
rc->postfix = postfix;
|
rc->postfix = postfix;
|
||||||
rc->promise = promise ? gst_promise_ref (promise) : NULL;
|
rc->promise = promise ? gst_promise_ref (promise) : NULL;
|
||||||
resolve_host_async (nice, address,
|
resolve_host_async (nice, address,
|
||||||
(GAsyncReadyCallback) on_candidate_resolved, rc,
|
on_candidate_resolved, rc,
|
||||||
(GDestroyNotify) free_resolve_candidate_data);
|
(GDestroyNotify) free_resolve_candidate_data);
|
||||||
|
|
||||||
prefix = NULL;
|
prefix = NULL;
|
||||||
|
@ -1341,13 +1376,10 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_http_proxy_resolved (GstWebRTCICE * ice, GAsyncResult * res,
|
on_http_proxy_resolved (GstWebRTCNice * nice, GList * addresses,
|
||||||
gpointer user_data)
|
GError * error, gpointer user_data)
|
||||||
{
|
{
|
||||||
GstWebRTCNice *nice = GST_WEBRTC_NICE (ice);
|
|
||||||
GstUri *uri = user_data;
|
GstUri *uri = user_data;
|
||||||
GList *addresses;
|
|
||||||
GError *error = NULL;
|
|
||||||
const gchar *userinfo;
|
const gchar *userinfo;
|
||||||
gchar *user = NULL;
|
gchar *user = NULL;
|
||||||
gchar *pass = NULL;
|
gchar *pass = NULL;
|
||||||
|
@ -1356,17 +1388,26 @@ on_http_proxy_resolved (GstWebRTCICE * ice, GAsyncResult * res,
|
||||||
guint port = GST_URI_NO_PORT;
|
guint port = GST_URI_NO_PORT;
|
||||||
GHashTable *extra_headers;
|
GHashTable *extra_headers;
|
||||||
|
|
||||||
if (!(addresses = resolve_host_finish (nice, res, &error))) {
|
if (error) {
|
||||||
GST_WARNING_OBJECT (ice, "Failed to resolve http proxy: %s",
|
if (nice) {
|
||||||
|
GST_WARNING_OBJECT (nice, "Failed to resolve http proxy: %s",
|
||||||
error->message);
|
error->message);
|
||||||
g_clear_error (&error);
|
} else {
|
||||||
|
GST_WARNING ("Failed to resolve http proxy: %s", error->message);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!nice) {
|
||||||
|
GST_WARNING ("Missing GstWebRTCNice instance");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstWebRTCICE *ice = GST_WEBRTC_ICE (nice);
|
||||||
|
|
||||||
/* XXX: only the first IP is used */
|
/* XXX: only the first IP is used */
|
||||||
ip = g_inet_address_to_string (addresses->data);
|
ip = g_inet_address_to_string (addresses->data);
|
||||||
g_resolver_free_addresses (addresses);
|
|
||||||
addresses = NULL;
|
|
||||||
|
|
||||||
if (!ip) {
|
if (!ip) {
|
||||||
GST_ERROR_OBJECT (ice, "failed to resolve host for proxy");
|
GST_ERROR_OBJECT (ice, "failed to resolve host for proxy");
|
||||||
|
@ -1444,7 +1485,7 @@ _set_http_proxy (GstWebRTCICE * ice, const gchar * s)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve_host_async (nice, host, (GAsyncReadyCallback) on_http_proxy_resolved,
|
resolve_host_async (nice, host, on_http_proxy_resolved,
|
||||||
gst_uri_ref (uri), (GDestroyNotify) gst_uri_unref);
|
gst_uri_ref (uri), (GDestroyNotify) gst_uri_unref);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in a new issue