The network_table hash removal function remove_network() cannot
be used because of we might have invalidated the DHCP connection
already and then we would try to do it again when DHCP stops.

So when DHCP is stopped, we now remove the corresponding network
from the hash manually. This way we are able to unref the network
because we have a pointer to it (the pointer was lost in earlier version)
and valgrind does not report possibly lost memory for network struct
anymore.
---
 src/dhcp.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/src/dhcp.c b/src/dhcp.c
index 168697d..e4bac67 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -86,6 +86,7 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, bool 
callback)
 {
        struct connman_service *service;
        struct connman_ipconfig *ipconfig;
+       bool network_removed = false;
        int i;
 
        DBG("dhcp %p callback %u", dhcp, callback);
@@ -131,10 +132,17 @@ static void dhcp_invalidate(struct connman_dhcp *dhcp, 
bool callback)
        __connman_ipconfig_set_gateway(ipconfig, NULL);
        __connman_ipconfig_set_prefixlen(ipconfig, 0);
 
-       if (dhcp->callback && callback)
+       if (dhcp->callback && callback) {
+               g_hash_table_remove(network_table, dhcp->network);
+               network_removed = true;
                dhcp->callback(dhcp->network, false, NULL);
+       }
 
 out:
+       if (!network_removed)
+               g_hash_table_remove(network_table, dhcp->network);
+
+       connman_network_unref(dhcp->network);
        dhcp_free(dhcp);
 }
 
@@ -584,16 +592,6 @@ static int dhcp_release(struct connman_dhcp *dhcp)
        return 0;
 }
 
-static void remove_network(gpointer user_data)
-{
-       struct connman_dhcp *dhcp = user_data;
-
-       DBG("dhcp %p", dhcp);
-
-       dhcp_release(dhcp);
-       dhcp_invalidate(dhcp, false);
-}
-
 int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback)
 {
        struct connman_dhcp *dhcp;
@@ -616,13 +614,20 @@ int __connman_dhcp_start(struct connman_network *network, 
dhcp_cb callback)
 
 void __connman_dhcp_stop(struct connman_network *network)
 {
-       DBG("");
+       struct connman_dhcp *dhcp;
+
+       DBG("network_table %p network %p", network_table, network);
 
        if (!network_table)
                return;
 
-       if (g_hash_table_remove(network_table, network))
-               connman_network_unref(network);
+       dhcp = g_hash_table_lookup(network_table, network);
+       g_hash_table_remove(network_table, network);
+
+       if (dhcp) {
+               dhcp_release(dhcp);
+               dhcp_invalidate(dhcp, false);
+       }
 }
 
 int __connman_dhcp_init(void)
@@ -630,7 +635,7 @@ int __connman_dhcp_init(void)
        DBG("");
 
        network_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-                                                       NULL, remove_network);
+                                                       NULL, NULL);
 
        return 0;
 }
-- 
1.8.3.1

_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman

Reply via email to