From: Daniel Wagner <[email protected]>

A session config object is created either with a default settings (by
issuing connman_session_create_default_config()) or from a config file
(see next patch). There is only one config object per session or
config file. That means that the ownership and life time is slightly more
complex.

So here are the rules on the lifetime:

- No config file: Created as result of policy_ivi_create() and destroyed
  apon policy_ivi_destroy()
- No session: Created when file is found, destroyed when file
  is gone
- As long there is either a session or a file, the config object exists.
- The config object will be destroyed when there is no session or
  file.

That means the config object life time can't be made depend on the
hash table entries. So we can't assume when we remove the the key from
the session_hash we can destroy the config object too. That's why we
don't use the cleanup hooks from the hash table directly.
---
 plugins/session_policy_ivi.c | 71 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)

diff --git a/plugins/session_policy_ivi.c b/plugins/session_policy_ivi.c
index 098c54c..df341a3 100644
--- a/plugins/session_policy_ivi.c
+++ b/plugins/session_policy_ivi.c
@@ -38,12 +38,32 @@
 
 static DBusConnection *connection;
 
+static GHashTable *session_hash;
+
 struct create_data {
        struct connman_session *session;
        connman_session_config_cb callback;
        void *user_data;
 };
 
+struct policy_data {
+       struct connman_session *session;
+
+       struct connman_session_config *config;
+};
+
+static void cleanup_policy(struct policy_data *policy)
+{
+       if (policy == NULL)
+               return;
+
+       if (policy->config != NULL)
+               connman_session_free_bearers(policy->config->allowed_bearers);
+
+       g_free(policy->config);
+       g_free(policy);
+}
+
 static char *parse_ident(const unsigned char *context)
 {
        char *str, *ident, **tokens;
@@ -90,6 +110,7 @@ static char *parse_ident(const unsigned char *context)
 static void selinux_context_reply(const unsigned char *context, void 
*user_data)
 {
        struct create_data *data = user_data;
+       struct policy_data *policy = NULL;
        char *ident;
 
        DBG("session %p", data->session);
@@ -98,7 +119,26 @@ static void selinux_context_reply(const unsigned char 
*context, void *user_data)
 
        DBG("ident %s", ident);
 
-       (*data->callback)(data->session, NULL, data->user_data, 0);
+       policy = g_try_new0(struct policy_data, 1);
+       if (policy == NULL)
+               goto err;
+
+       policy->config = connman_session_create_default_config();
+       if (policy->config == NULL)
+               goto err;
+
+       g_hash_table_replace(session_hash, data->session, policy);
+
+       (*data->callback)(data->session, policy->config, data->user_data, 0);
+
+       g_free(data);
+       g_free(ident);
+
+       return;
+err:
+       (*data->callback)(data->session, NULL, data->user_data, -ENOMEM);
+
+       cleanup_policy(policy);
 
        g_free(data);
        g_free(ident);
@@ -138,7 +178,15 @@ static int policy_ivi_create(struct connman_session 
*session,
 
 static void policy_ivi_destroy(struct connman_session *session)
 {
+       struct policy_data *policy;
+
        DBG("session %p", session);
+
+       policy = g_hash_table_lookup(session_hash, session);
+
+       g_hash_table_remove(session_hash, session);
+
+       cleanup_policy(policy);
 }
 
 static struct connman_session_policy session_policy_ivi = {
@@ -160,6 +208,14 @@ static int session_policy_ivi_init(void)
        if (err < 0)
                goto err;
 
+       session_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+                                               NULL, NULL);
+       if (session_hash == NULL) {
+               err = -ENOMEM;
+               connman_session_policy_unregister(&session_policy_ivi);
+               goto err;
+       }
+
        return 0;
 
 err:
@@ -170,6 +226,19 @@ err:
 
 static void session_policy_ivi_exit(void)
 {
+       GHashTableIter iter;
+       gpointer key, value;
+
+       g_hash_table_iter_init(&iter, session_hash);
+
+       while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+               struct policy_data *data = value;
+
+               cleanup_policy(data);
+       }
+
+       g_hash_table_destroy(session_hash);
+
        connman_session_policy_unregister(&session_policy_ivi);
 
        dbus_connection_unref(connection);
-- 
1.8.0.rc0

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

Reply via email to