X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-session.c;h=8c0f77b85ddfd150832f7379c43c5b9961de856a;hb=c8558c8a28966110aa3a356f95d3c60afe32b64a;hp=88d5b0d2b62d0718ebd9fa31eb54484cd21c1599;hpb=d45426257d5149c735e33e3055220625a919e7bc;p=src%2Fapp-framework-binder.git diff --git a/src/afb-session.c b/src/afb-session.c index 88d5b0d2..8c0f77b8 100644 --- a/src/afb-session.c +++ b/src/afb-session.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" + * Copyright (C) 2015-2018 "IoT.bzh" * Author "Fulup Ar Foll" * Author: José Bollo * @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include "afb-session.h" +#include "afb-hook.h" #include "verbose.h" #define SIZEUUID 37 @@ -39,7 +41,7 @@ #define _MAXEXP_ ((time_t)(~(time_t)0)) #define _MAXEXP2_ ((time_t)((((unsigned long long)_MAXEXP_) >> 1))) #define MAX_EXPIRATION (_MAXEXP_ >= 0 ? _MAXEXP_ : _MAXEXP2_) -#define NOW (time(NULL)) +#define NOW (time_now()) /* structure for a cookie added to sessions */ struct cookie @@ -85,6 +87,14 @@ static struct { .mutex = PTHREAD_MUTEX_INITIALIZER }; +/* Get the actual raw time */ +static inline time_t time_now() +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + return ts.tv_sec; +} + /* generate a new fresh 'uuid' */ static void new_uuid(char uuid[SIZEUUID]) { @@ -189,9 +199,13 @@ static void session_close(struct afb_session *session) /* close only one time */ if (!session->closed) { + /* close it now */ session->closed = 1; - /* free cookies */ + /* emit the hook */ + afb_hook_session_close(session); + + /* release cookies */ for (idx = 0 ; idx < COOKIECOUNT ; idx++) { while ((cookie = session->cookies[idx])) { session->cookies[idx] = cookie->next; @@ -206,6 +220,7 @@ static void session_close(struct afb_session *session) /* destroy the 'session' */ static void session_destroy (struct afb_session *session) { + afb_hook_session_destroy(session); pthread_mutex_destroy(&session->mutex); free(session); } @@ -213,21 +228,12 @@ static void session_destroy (struct afb_session *session) /* update expiration of 'session' according to 'now' */ static void session_update_expiration(struct afb_session *session, time_t now) { - int timeout; time_t expiration; /* compute expiration */ - timeout = session->timeout; - if (timeout == AFB_SESSION_TIMEOUT_INFINITE) + expiration = now + afb_session_timeout(session); + if (expiration < 0) expiration = MAX_EXPIRATION; - else { - if (timeout == AFB_SESSION_TIMEOUT_DEFAULT) - expiration = now + sessions.timeout; - else - expiration = now + timeout; - if (expiration < 0) - expiration = MAX_EXPIRATION; - } /* record the expiration */ session->expiration = expiration; @@ -271,6 +277,8 @@ static struct afb_session *session_add(const char *uuid, int timeout, time_t now return NULL; } + afb_hook_session_create(session); + return session; } @@ -338,6 +346,28 @@ int afb_session_init (int max_session_count, int timeout, const char *initok) return 0; } +/** + * Iterate the sessions and call 'callback' with + * the 'closure' for each session. + */ +void afb_session_foreach(void (*callback)(void *closure, struct afb_session *session), void *closure) +{ + struct afb_session *session; + int idx; + + /* Loop on Sessions Table and remove anything that is older than timeout */ + sessionset_lock(); + for (idx = 0 ; idx < HEADCOUNT; idx++) { + session = sessions.heads[idx]; + while (session) { + if (!session->closed) + callback(closure, session); + session = session->next; + } + } + sessionset_unlock(); +} + /** * Cleanup the sessionset of its closed or expired sessions */ @@ -378,6 +408,30 @@ struct afb_session *afb_session_create (int timeout) return afb_session_get(NULL, timeout, NULL); } +/** + * Returns the timeout of 'session' in seconds + */ +int afb_session_timeout(struct afb_session *session) +{ + int timeout; + + /* compute timeout */ + timeout = session->timeout; + if (timeout == AFB_SESSION_TIMEOUT_DEFAULT) + timeout = sessions.timeout; + if (timeout < 0) + timeout = INT_MAX; + return timeout; +} + +/** + * Returns the second remaining before expiration of 'session' + */ +int afb_session_what_remains(struct afb_session *session) +{ + return (int)(session->expiration - NOW); +} + /* This function will return exiting session or newly created session */ struct afb_session *afb_session_get (const char *uuid, int timeout, int *created) { @@ -419,8 +473,12 @@ end: /* increase the use count on 'session' (can be NULL) */ struct afb_session *afb_session_addref(struct afb_session *session) { - if (session != NULL) - __atomic_add_fetch(&session->refcount, 1, __ATOMIC_RELAXED); + if (session != NULL) { + afb_hook_session_addref(session); + session_lock(session); + session->refcount++; + session_unlock(session); + } return session; } @@ -430,8 +488,9 @@ void afb_session_unref(struct afb_session *session) if (session == NULL) return; + afb_hook_session_unref(session); session_lock(session); - if (!__atomic_sub_fetch(&session->refcount, 1, __ATOMIC_RELAXED)) { + if (!--session->refcount) { if (session->autoclose) session_close(session); if (session->notinset) { @@ -489,11 +548,11 @@ int afb_session_check_token (struct afb_session *session, const char *token) /* generate a new token and update client context */ void afb_session_new_token (struct afb_session *session) { - /* Old token was valid let's regenerate a new one */ + session_unlock(session); new_uuid(session->token); - - /* keep track of time for session timeout and further clean up */ session_update_expiration(session, NOW); + afb_hook_session_renew(session); + session_unlock(session); } /* Returns the uuid of 'session' */