summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorHyunjee Kim <hj0426.kim@samsung.com>2019-12-03 10:54:26 +0900
committerHyunjee Kim <hj0426.kim@samsung.com>2019-12-03 10:54:26 +0900
commit25d63acb6a98478b3fd901735198f87c644ffa64 (patch)
tree117e1ec3df0f694decaf12b8b909904523006607 /gio
parent691482adab5cd530f5a570d9c5e7ab1d99552add (diff)
downloadglib-25d63acb6a98478b3fd901735198f87c644ffa64.tar.gz
glib-25d63acb6a98478b3fd901735198f87c644ffa64.tar.bz2
glib-25d63acb6a98478b3fd901735198f87c644ffa64.zip
Imported Upstream version 2.60.7
Diffstat (limited to 'gio')
-rw-r--r--gio/gapplication.c3
-rw-r--r--gio/gsettingsbackend.c41
-rw-r--r--gio/gvfs.c10
-rw-r--r--gio/win32/gwinhttpfile.c2
-rw-r--r--gio/win32/gwinhttpvfs.c18
5 files changed, 48 insertions, 26 deletions
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 2d2ab48e3..321b34f54 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -1372,6 +1372,9 @@ g_application_finalize (GObject *object)
{
GApplication *application = G_APPLICATION (object);
+ if (application->priv->inactivity_timeout_id)
+ g_source_remove (application->priv->inactivity_timeout_id);
+
g_slist_free_full (application->priv->option_groups, (GDestroyNotify) g_option_group_unref);
if (application->priv->main_options)
g_option_group_unref (application->priv->main_options);
diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c
index 18026ae56..f53a02392 100644
--- a/gio/gsettingsbackend.c
+++ b/gio/gsettingsbackend.c
@@ -122,7 +122,13 @@ is_path (const gchar *path)
struct _GSettingsBackendWatch
{
- GObject *target;
+ /* Always access the target via the weak reference */
+ GWeakRef target;
+ /* The pointer is only for comparison from the weak notify,
+ * at which point the target might already be close to
+ * destroyed. It's not safe to use it for anything anymore
+ * at that point */
+ GObject *target_ptr;
const GSettingsListenerVTable *vtable;
GMainContext *context;
GSettingsBackendWatch *next;
@@ -137,7 +143,7 @@ struct _GSettingsBackendClosure
gchar **names);
GMainContext *context;
- GWeakRef *target_ref;
+ GObject *target;
GSettingsBackend *backend;
gchar *name;
gpointer origin_tag;
@@ -154,11 +160,12 @@ g_settings_backend_watch_weak_notify (gpointer data,
/* search and remove */
g_mutex_lock (&backend->priv->lock);
for (ptr = &backend->priv->watches; *ptr; ptr = &(*ptr)->next)
- if ((*ptr)->target == where_the_object_was)
+ if ((*ptr)->target_ptr == where_the_object_was)
{
GSettingsBackendWatch *tmp = *ptr;
*ptr = tmp->next;
+ g_weak_ref_clear (&tmp->target);
g_slice_free (GSettingsBackendWatch, tmp);
g_mutex_unlock (&backend->priv->lock);
@@ -208,9 +215,10 @@ g_settings_backend_watch (GSettingsBackend *backend,
* GSettings object in a thread other than the one that is doing the
* dispatching is as follows:
*
- * 1) hold a thread-safe GWeakRef on the GSettings during an outstanding
+ * 1) hold a strong reference on the GSettings during an outstanding
* dispatch. This ensures that the delivery is always possible while
- * the GSettings object is alive.
+ * the GSettings object is alive, and if this was the last reference
+ * then it will be dropped from the dispatch thread.
*
* 2) hold a weak reference on the GSettings at other times. This
* allows us to receive early notification of pending destruction
@@ -235,7 +243,8 @@ g_settings_backend_watch (GSettingsBackend *backend,
watch = g_slice_new (GSettingsBackendWatch);
watch->context = context;
watch->vtable = vtable;
- watch->target = target;
+ g_weak_ref_init (&watch->target, target);
+ watch->target_ptr = target;
g_object_weak_ref (target, g_settings_backend_watch_weak_notify, backend);
/* linked list prepend */
@@ -260,20 +269,14 @@ static gboolean
g_settings_backend_invoke_closure (gpointer user_data)
{
GSettingsBackendClosure *closure = user_data;
- GObject *target = g_weak_ref_get (closure->target_ref);
- if (target)
- {
- closure->function (target, closure->backend, closure->name,
- closure->origin_tag, closure->names);
- g_object_unref (target);
- }
+ closure->function (closure->target, closure->backend, closure->name,
+ closure->origin_tag, closure->names);
if (closure->context)
g_main_context_unref (closure->context);
g_object_unref (closure->backend);
- g_weak_ref_clear (closure->target_ref);
- g_free (closure->target_ref);
+ g_object_unref (closure->target);
g_strfreev (closure->names);
g_free (closure->name);
@@ -304,14 +307,18 @@ g_settings_backend_dispatch_signal (GSettingsBackend *backend,
for (watch = backend->priv->watches; watch; watch = watch->next)
{
GSettingsBackendClosure *closure;
+ GObject *target = g_weak_ref_get (&watch->target);
+
+ /* If the target was destroyed in the meantime, just skip it here */
+ if (!target)
+ continue;
closure = g_slice_new (GSettingsBackendClosure);
closure->context = watch->context;
if (closure->context)
g_main_context_ref (closure->context);
closure->backend = g_object_ref (backend);
- closure->target_ref = g_new (GWeakRef, 1);
- g_weak_ref_init (closure->target_ref, watch->target);
+ closure->target = g_steal_pointer (&target);
closure->function = G_STRUCT_MEMBER (void *, watch->vtable,
function_offset);
closure->name = g_strdup (name);
diff --git a/gio/gvfs.c b/gio/gvfs.c
index 5805a7904..3475624cf 100644
--- a/gio/gvfs.c
+++ b/gio/gvfs.c
@@ -236,7 +236,7 @@ g_vfs_get_file_for_uri (GVfs *vfs,
const char *uri)
{
GVfsClass *class;
- GFile *ret;
+ GFile *ret = NULL;
g_return_val_if_fail (G_IS_VFS (vfs), NULL);
g_return_val_if_fail (uri != NULL, NULL);
@@ -244,10 +244,12 @@ g_vfs_get_file_for_uri (GVfs *vfs,
class = G_VFS_GET_CLASS (vfs);
ret = get_file_for_uri_internal (vfs, uri);
- if (ret)
- return ret;
+ if (!ret)
+ ret = (* class->get_file_for_uri) (vfs, uri);
+
+ g_assert (ret != NULL);
- return (* class->get_file_for_uri) (vfs, uri);
+ return g_steal_pointer (&ret);
}
/**
diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c
index d5df16d91..d6acab7b8 100644
--- a/gio/win32/gwinhttpfile.c
+++ b/gio/win32/gwinhttpfile.c
@@ -80,7 +80,7 @@ g_winhttp_file_init (GWinHttpFile *winhttp)
* @vfs: GWinHttpVfs to use
* @uri: URI of the GWinHttpFile to create.
*
- * Returns: new winhttp #GFile.
+ * Returns: (nullable): new winhttp #GFile, or %NULL if there was an error constructing it.
*/
GFile *
_g_winhttp_file_new (GWinHttpVfs *vfs,
diff --git a/gio/win32/gwinhttpvfs.c b/gio/win32/gwinhttpvfs.c
index 038368f81..91d7fed9d 100644
--- a/gio/win32/gwinhttpvfs.c
+++ b/gio/win32/gwinhttpvfs.c
@@ -165,15 +165,25 @@ g_winhttp_vfs_get_file_for_uri (GVfs *vfs,
{
GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs);
int i;
+ GFile *ret = NULL;
/* If it matches one of "our" schemes, handle it */
for (i = 0; i < G_N_ELEMENTS (winhttp_uri_schemes); i++)
- if (g_ascii_strncasecmp (uri, winhttp_uri_schemes[i], strlen (winhttp_uri_schemes[i])) == 0 &&
- uri[strlen (winhttp_uri_schemes[i])] == ':')
- return _g_winhttp_file_new (winhttp_vfs, uri);
+ {
+ if (g_ascii_strncasecmp (uri, winhttp_uri_schemes[i], strlen (winhttp_uri_schemes[i])) == 0 &&
+ uri[strlen (winhttp_uri_schemes[i])] == ':')
+ {
+ ret = _g_winhttp_file_new (winhttp_vfs, uri);
+ }
+ }
/* For other URIs fallback to the wrapped GVfs */
- return g_vfs_get_file_for_uri (winhttp_vfs->wrapped_vfs, uri);
+ if (ret == NULL)
+ ret = g_vfs_get_file_for_uri (winhttp_vfs->wrapped_vfs, uri);
+
+ g_assert (ret != NULL);
+
+ return g_steal_pointer (&ret);
}
static const gchar * const *