diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-11-06 23:01:42 +0100 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-11-06 23:01:42 +0100 |
commit | f26355dd547b32124ce6439ad48487cb71278c76 (patch) | |
tree | 57e081178ca609ee2f75e71752254e5d698e204f | |
parent | 5bffa91c6c719b828a317adfb913ce57dbb2c6f0 (diff) |
afb-session: fix reference counting
Change-Id: If36c9210f0982ba35299de52f0c8fd96e7c836e2
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/afb-session.c | 16 | ||||
-rw-r--r-- | src/afb-trace.c | 12 |
2 files changed, 21 insertions, 7 deletions
diff --git a/src/afb-session.c b/src/afb-session.c index 3befb92e..8f807615 100644 --- a/src/afb-session.c +++ b/src/afb-session.c @@ -161,6 +161,7 @@ static void destroy (struct afb_session *session) assert (session != NULL); + remove_all_cookies(session); pthread_mutex_lock(&sessions.mutex); prv = &sessions.heads[(int)session->idx]; while (*prv) @@ -293,6 +294,8 @@ struct afb_session *afb_session_search (const char *uuid) pthread_mutex_lock(&sessions.mutex); cleanup(); session = search(uuid, pearson4(uuid)); + if (session) + __atomic_add_fetch(&session->refcount, 1, __ATOMIC_RELAXED); pthread_mutex_unlock(&sessions.mutex); return session; @@ -315,7 +318,7 @@ struct afb_session *afb_session_get (const char *uuid, int timeout, int *created else { idx = pearson4(uuid); session = search(uuid, idx); - if (session != NULL) { + if (session) { __atomic_add_fetch(&session->refcount, 1, __ATOMIC_RELAXED); pthread_mutex_unlock(&sessions.mutex); if (created) @@ -346,8 +349,11 @@ void afb_session_unref(struct afb_session *session) if (session != NULL) { assert(session->refcount != 0); if (!__atomic_sub_fetch(&session->refcount, 1, __ATOMIC_RELAXED)) { + pthread_mutex_lock(&session->mutex); if (session->uuid[0] == 0) destroy (session); + else + pthread_mutex_unlock(&session->mutex); } } } @@ -356,12 +362,16 @@ void afb_session_unref(struct afb_session *session) void afb_session_close (struct afb_session *session) { assert(session != NULL); + pthread_mutex_lock(&session->mutex); if (session->uuid[0] != 0) { session->uuid[0] = 0; - remove_all_cookies(session); - if (session->refcount == 0) + remove_all_cookies(session); + if (session->refcount == 0) { destroy (session); + return; + } } + pthread_mutex_unlock(&session->mutex); } // Sample Generic Ping Debug API diff --git a/src/afb-trace.c b/src/afb-trace.c index f0efd5f3..021ab5af 100644 --- a/src/afb-trace.c +++ b/src/afb-trace.c @@ -1211,17 +1211,19 @@ static void addhook(struct desc *desc, enum trace_type type) /* create the hook handler */ switch (type) { case Trace_Type_Xreq: - if (desc->session) { + if (!desc->session) + session = afb_session_addref(bind); + else { session = trace_get_session_by_uuid(trace, desc->session, 1); if (!session) { ctxt_error(&desc->context->errors, "allocation of session failed"); free(hook); return; } - bind = session; } - hook->handler = afb_hook_create_xreq(desc->api, desc->verb, bind, + hook->handler = afb_hook_create_xreq(desc->api, desc->verb, session, desc->flags[type], &hook_xreq_itf, hook); + afb_session_unref(session); break; case Trace_Type_Ditf: hook->handler = afb_hook_create_ditf(desc->api, desc->flags[type], &hook_ditf_itf, hook); @@ -1423,8 +1425,10 @@ static void drop_session(void *closure, struct json_object *object) session = trace_get_session_by_uuid(context->trace, uuid, 0); if (!session) ctxt_error(&context->errors, "session %s not found", uuid); - else + else { trace_unhook(context->trace, NULL, NULL, session); + afb_session_unref(session); + } } } |