X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-stub-ws.c;h=37607ee0d4afa2c2fd73e3b34a9bc5845aec1e7e;hb=9e8fda2954d951ea819dbddfe5afe466b2306074;hp=8533c7979cc9cce27ab4adbae84c588570f10e8b;hpb=f11c11123f8cc43fc6e810b6c3dd911eb697826e;p=src%2Fapp-framework-binder.git diff --git a/src/afb-stub-ws.c b/src/afb-stub-ws.c index 8533c797..37607ee0 100644 --- a/src/afb-stub-ws.c +++ b/src/afb-stub-ws.c @@ -36,8 +36,6 @@ #include -#include "afb-common.h" - #include "afb-session.h" #include "afb-cred.h" #include "afb-api.h" @@ -48,6 +46,7 @@ #include "afb-evt.h" #include "afb-xreq.h" #include "verbose.h" +#include "fdev.h" #include "jobs.h" struct afb_stub_ws; @@ -125,6 +124,15 @@ struct server_describe struct afb_proto_ws_describe *describe; }; +/* + * structure for recording sessions + */ +struct server_session +{ + struct server_session *next; + struct afb_session *session; +}; + /******************* stub description for client or servers ******************/ struct afb_stub_ws @@ -147,6 +155,9 @@ struct afb_stub_ws /* credentials (server side) */ struct afb_cred *cred; + /* sessions (server side) */ + struct server_session *sessions; + /* apiset */ struct afb_apiset *apiset; @@ -460,6 +471,46 @@ static void on_subcall(void *closure, struct afb_proto_ws_subcall *subcall, void /*****************************************************/ +static void record_session(struct afb_stub_ws *stubws, struct afb_session *session) +{ + struct server_session *s, **prv; + + /* search */ + prv = &stubws->sessions; + while ((s = *prv)) { + if (s->session == session) + return; + if (afb_session_is_closed(s->session)) { + *prv = s->next; + afb_session_unref(s->session); + free(s); + } + else + prv = &s->next; + } + + /* create */ + s = malloc(sizeof *s); + if (s) { + s->session = afb_session_addref(session); + s->next = stubws->sessions; + stubws->sessions = s; + } +} + +static void release_sessions(struct afb_stub_ws *stubws) +{ + struct server_session *s; + + while((s = stubws->sessions)) { + stubws->sessions = s->next; + afb_session_unref(s->session); + free(s); + } +} + +/*****************************************************/ + static void on_call(void *closure, struct afb_proto_ws_call *call, const char *verb, struct json_object *args, const char *sessionid) { struct afb_stub_ws *stubws = closure; @@ -479,6 +530,10 @@ static void on_call(void *closure, struct afb_proto_ws_call *call, const char *v /* init the context */ if (afb_context_connect(&wreq->xreq.context, sessionid, NULL) < 0) goto unconnected; + wreq->xreq.context.validated = 1; + record_session(stubws, wreq->xreq.context.session); + if (wreq->xreq.context.created) + afb_session_set_autoclose(wreq->xreq.context.session, 1); /* makes the call */ wreq->xreq.cred = afb_cred_addref(stubws->cred); @@ -595,13 +650,17 @@ static void on_hangup(void *closure) { struct afb_stub_ws *stubws = closure; + afb_stub_ws_addref(stubws); if (stubws->on_hangup) stubws->on_hangup(stubws); + + release_sessions(stubws); + afb_stub_ws_unref(stubws); } /*****************************************************/ -static struct afb_stub_ws *afb_stub_ws_create(int fd, const char *apiname, struct afb_apiset *apiset, int client) +static struct afb_stub_ws *afb_stub_ws_create(struct fdev *fdev, const char *apiname, struct afb_apiset *apiset, int client) { struct afb_stub_ws *stubws; @@ -610,10 +669,11 @@ static struct afb_stub_ws *afb_stub_ws_create(int fd, const char *apiname, struc errno = ENOMEM; else { if (client) - stubws->proto = afb_proto_ws_create_client(afb_common_get_event_loop(), fd, &client_itf, stubws); + stubws->proto = afb_proto_ws_create_client(fdev, &client_itf, stubws); else - stubws->proto = afb_proto_ws_create_server(afb_common_get_event_loop(), fd, &server_itf, stubws); - if (stubws->proto != NULL) { + stubws->proto = afb_proto_ws_create_server(fdev, &server_itf, stubws); + + if (stubws->proto) { strcpy(stubws->apiname, apiname); stubws->apiset = afb_apiset_addref(apiset); stubws->refcount = 1; @@ -622,21 +682,22 @@ static struct afb_stub_ws *afb_stub_ws_create(int fd, const char *apiname, struc } free(stubws); } + fdev_unref(fdev); return NULL; } -struct afb_stub_ws *afb_stub_ws_create_client(int fd, const char *apiname, struct afb_apiset *apiset) +struct afb_stub_ws *afb_stub_ws_create_client(struct fdev *fdev, const char *apiname, struct afb_apiset *apiset) { - return afb_stub_ws_create(fd, apiname, apiset, 1); + return afb_stub_ws_create(fdev, apiname, apiset, 1); } -struct afb_stub_ws *afb_stub_ws_create_server(int fd, const char *apiname, struct afb_apiset *apiset) +struct afb_stub_ws *afb_stub_ws_create_server(struct fdev *fdev, const char *apiname, struct afb_apiset *apiset) { struct afb_stub_ws *stubws; - stubws = afb_stub_ws_create(fd, apiname, apiset, 0); + stubws = afb_stub_ws_create(fdev, apiname, apiset, 0); if (stubws) { - stubws->cred = afb_cred_create_for_socket(fd); + stubws->cred = afb_cred_create_for_socket(fdev_fd(fdev)); stubws->listener = afb_evt_listener_create(&server_evt_itf, stubws); if (stubws->listener != NULL) return stubws; @@ -649,7 +710,9 @@ void afb_stub_ws_unref(struct afb_stub_ws *stubws) { if (!__atomic_sub_fetch(&stubws->refcount, 1, __ATOMIC_RELAXED)) { drop_all_events(stubws); - afb_evt_listener_unref(stubws->listener); + if (stubws->listener) + afb_evt_listener_unref(stubws->listener); + release_sessions(stubws); afb_proto_ws_unref(stubws->proto); afb_cred_unref(stubws->cred); afb_apiset_unref(stubws->apiset);