Atomic context initialisation for bindings
[src/app-framework-binder.git] / src / afb-session.c
index 536cdbc..61bce09 100644 (file)
@@ -120,7 +120,7 @@ static void free_data (struct afb_session *session)
 void afb_session_init (int max_session_count, int timeout, const char *initok)
 {
        // let's create as store as hashtable does not have any
-       sessions.store = calloc (1 + (unsigned)max_session_count, sizeof(struct afb_session));
+       sessions.store = calloc (1 + (unsigned)max_session_count, sizeof *sessions.store);
        pthread_mutex_init(&sessions.mutex, NULL);
        sessions.max = max_session_count;
        sessions.timeout = timeout;
@@ -135,6 +135,11 @@ void afb_session_init (int max_session_count, int timeout, const char *initok)
        }
 }
 
+const char *afb_session_initial_token()
+{
+       return sessions.initok;
+}
+
 static struct afb_session *search (const char* uuid)
 {
        int  idx;
@@ -309,6 +314,8 @@ struct afb_session *afb_session_get (const char *uuid, int *created)
        /* search for an existing one not too old */
        if (uuid != NULL) {
                session = search(uuid);
+               if (!created)
+                       return session;
                if (session != NULL) {
                        *created = 0;
                        session->access = now;
@@ -317,7 +324,9 @@ struct afb_session *afb_session_get (const char *uuid, int *created)
                }
        }
 
-       *created = 1;
+       if (created)
+               *created = 1;
+
        return make_session(uuid, sessions.timeout, now);
 }
 
@@ -424,7 +433,7 @@ static struct cookie *cookie_add(struct afb_session *session, int idx, const voi
        return cookie;
 }
 
-void *afb_session_cookie(struct afb_session *session, const void *key, void *(*makecb)(void), void (*freecb)(void*))
+void *afb_session_cookie(struct afb_session *session, const void *key, void *(*makecb)(void *closure), void (*freecb)(void *item), void *closure, int replace)
 {
        int idx;
        void *value;
@@ -432,15 +441,23 @@ void *afb_session_cookie(struct afb_session *session, const void *key, void *(*m
 
        lock(session);
        cookie = cookie_search(session, key, &idx);
-       if (cookie)
-               value = cookie->value;
-       else {
-               value = makecb ? makecb() : NULL;
-               if (makecb || freecb) {
+       if (cookie) {
+               if (!replace)
+                       value = cookie->value;
+               else {
+                       value = makecb ? makecb(closure) : closure;
+                       if (cookie->value != value && cookie->freecb)
+                               cookie->freecb(cookie->value);
+                       cookie->value = value;
+                       cookie->freecb = freecb;
+               }
+       } else {
+               value = makecb ? makecb(closure) : closure;
+               if (replace || makecb || freecb) {
                        cookie = cookie_add(session, idx, key, value, freecb);
                        if (!cookie) {
                                if (makecb && freecb)
-                                       free(value);
+                                       freecb(value);
                                value = NULL;
                        }
                }