diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c
index 8e073fd..289fd56 100644
--- a/gio/gnetworkaddress.c
+++ b/gio/gnetworkaddress.c
@@ -63,6 +63,7 @@ struct _GNetworkAddressPrivate {
   guint16 port;
   GList *sockaddrs;
   gchar *scheme;
+  GMutex lock;
 
   gint64 resolver_serial;
 };
@@ -102,13 +103,12 @@ g_network_address_finalize (GObject *object)
 
   if (addr->priv->sockaddrs)
     {
-      GList *a;
-
-      for (a = addr->priv->sockaddrs; a; a = a->next)
-        g_object_unref (a->data);
-      g_list_free (addr->priv->sockaddrs);
+      g_list_free_full (addr->priv->sockaddrs, g_object_unref);
+      addr->priv->sockaddrs = NULL;
     }
 
+  g_mutex_clear (&addr->priv->lock);
+
   G_OBJECT_CLASS (g_network_address_parent_class)->finalize (object);
 }
 
@@ -159,6 +159,8 @@ static void
 g_network_address_init (GNetworkAddress *addr)
 {
   addr->priv = g_network_address_get_instance_private (addr);
+
+  g_mutex_init (&addr->priv->lock);
 }
 
 static void
@@ -222,9 +224,9 @@ g_network_address_get_property (GObject    *object,
 }
 
 static void
-g_network_address_set_addresses (GNetworkAddress *addr,
-                                 GList           *addresses,
-                                 guint64          resolver_serial)
+g_network_address_set_addresses_locked (GNetworkAddress *addr,
+                                        GList           *addresses,
+                                        guint64          resolver_serial)
 {
   GList *a;
   GSocketAddress *sockaddr;
@@ -244,7 +246,7 @@ g_network_address_set_addresses (GNetworkAddress *addr,
 }
 
 static gboolean
-g_network_address_parse_sockaddr (GNetworkAddress *addr)
+g_network_address_parse_sockaddr_locked (GNetworkAddress *addr)
 {
   GSocketAddress *sockaddr;
 
@@ -321,7 +323,10 @@ g_network_address_new_loopback (guint16 port)
 
   addrs = g_list_append (addrs, g_inet_address_new_loopback (AF_INET6));
   addrs = g_list_append (addrs, g_inet_address_new_loopback (AF_INET));
-  g_network_address_set_addresses (addr, addrs, 0);
+
+  g_mutex_lock (&addr->priv->lock);
+  g_network_address_set_addresses_locked (addr, addrs, 0);
+  g_mutex_unlock (&addr->priv->lock);
 
   return G_SOCKET_CONNECTABLE (addr);
 }
@@ -911,6 +916,8 @@ g_network_address_address_enumerator_next (GSocketAddressEnumerator  *enumerator
       GResolver *resolver = g_resolver_get_default ();
       gint64 serial = g_resolver_get_serial (resolver);
 
+      g_mutex_lock (&addr->priv->lock);
+
       if (addr->priv->resolver_serial != 0 &&
           addr->priv->resolver_serial != serial)
         {
@@ -920,7 +927,7 @@ g_network_address_address_enumerator_next (GSocketAddressEnumerator  *enumerator
         }
 
       if (!addr->priv->sockaddrs)
-        g_network_address_parse_sockaddr (addr);
+        g_network_address_parse_sockaddr_locked (addr);
       if (!addr->priv->sockaddrs)
         {
           GList *addresses;
@@ -931,15 +938,18 @@ g_network_address_address_enumerator_next (GSocketAddressEnumerator  *enumerator
           if (!addresses)
             {
               g_object_unref (resolver);
+              g_mutex_unlock (&addr->priv->lock);
               return NULL;
             }
 
-          g_network_address_set_addresses (addr, addresses, serial);
+          g_network_address_set_addresses_locked (addr, addresses, serial);
         }
           
       addr_enum->addresses = addr->priv->sockaddrs;
       addr_enum->next = addr_enum->addresses;
       g_object_unref (resolver);
+
+      g_mutex_unlock (&addr->priv->lock);
     }
 
   if (addr_enum->next == NULL)
@@ -956,6 +966,8 @@ have_addresses (GNetworkAddressAddressEnumerator *addr_enum,
 {
   GSocketAddress *sockaddr;
 
+  g_mutex_lock (&addr_enum->addr->priv->lock);
+
   addr_enum->addresses = addr_enum->addr->priv->sockaddrs;
   addr_enum->next = addr_enum->addresses;
 
@@ -967,6 +979,8 @@ have_addresses (GNetworkAddressAddressEnumerator *addr_enum,
   else
     sockaddr = NULL;
 
+  g_mutex_unlock (&addr_enum->addr->priv->lock);
+
   if (error)
     g_task_return_error (task, error);
   else
@@ -985,16 +999,21 @@ got_addresses (GObject      *source_object,
   GList *addresses;
   GError *error = NULL;
 
+  g_mutex_lock (&addr_enum->addr->priv->lock);
+
   if (!addr_enum->addr->priv->sockaddrs)
     {
       addresses = g_resolver_lookup_by_name_finish (resolver, result, &error);
 
       if (!error)
         {
-          g_network_address_set_addresses (addr_enum->addr, addresses,
-                                           g_resolver_get_serial (resolver));
+          g_network_address_set_addresses_locked (addr_enum->addr, addresses,
+                                                  g_resolver_get_serial (resolver));
         }
     }
+
+  g_mutex_unlock (&addr_enum->addr->priv->lock);
+
   have_addresses (addr_enum, task, error);
 }
 
@@ -1017,6 +1036,8 @@ g_network_address_address_enumerator_next_async (GSocketAddressEnumerator  *enum
       GResolver *resolver = g_resolver_get_default ();
       gint64 serial = g_resolver_get_serial (resolver);
 
+      g_mutex_lock (&addr->priv->lock);
+
       if (addr->priv->resolver_serial != 0 &&
           addr->priv->resolver_serial != serial)
         {
@@ -1027,10 +1048,14 @@ g_network_address_address_enumerator_next_async (GSocketAddressEnumerator  *enum
 
       if (!addr->priv->sockaddrs)
         {
-          if (g_network_address_parse_sockaddr (addr))
-            have_addresses (addr_enum, task, NULL);
+          if (g_network_address_parse_sockaddr_locked (addr))
+            {
+              g_mutex_unlock (&addr->priv->lock);
+              have_addresses (addr_enum, task, NULL);
+            }
           else
             {
+              g_mutex_unlock (&addr->priv->lock);
               g_resolver_lookup_by_name_async (resolver,
                                                addr->priv->hostname,
                                                cancellable,
@@ -1043,6 +1068,8 @@ g_network_address_address_enumerator_next_async (GSocketAddressEnumerator  *enum
       addr_enum->addresses = addr->priv->sockaddrs;
       addr_enum->next = addr_enum->addresses;
       g_object_unref (resolver);
+
+      g_mutex_unlock (&addr->priv->lock);
     }
 
   if (addr_enum->next)
