summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2014-04-03 12:39:18 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2014-04-03 13:05:59 +0300
commit85f960078fcb9cfbc7a146a187e1d0353cd2fa8b (patch)
treed9fa9aea3c3ba2d610f2c6e4aab805276858418b
parent9080023754638b56b9cae0524639ad3c4a98e2b4 (diff)
downloadconnman-85f960078fcb9cfbc7a146a187e1d0353cd2fa8b.tar.gz
dhcp: Network hash table fixes
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.
-rw-r--r--src/dhcp.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/src/dhcp.c b/src/dhcp.c
index 168697d2..e4bac674 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;
}