#include <afb/afb-event.h>
-#include "afb-common.h"
-
#include "afb-session.h"
#include "afb-cred.h"
#include "afb-api.h"
#include "afb-evt.h"
#include "afb-xreq.h"
#include "verbose.h"
+#include "fdev.h"
#include "jobs.h"
struct afb_stub_ws;
static void record_session(struct afb_stub_ws *stubws, struct afb_session *session)
{
- struct server_session *iter;
+ struct server_session *s, **prv;
/* search */
- for (iter = stubws->sessions ; iter ; iter = iter->next)
- if (iter->session == session)
+ 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 */
- iter = malloc(sizeof *iter);
- if (iter) {
- iter->session = afb_session_addref(session);
- iter->next = stubws->sessions;
- stubws->sessions = iter;
+ 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)
+static void release_all_sessions(struct afb_stub_ws *stubws)
{
- struct server_session *iter;
+ struct server_session *s, *n;
- while((iter = stubws->sessions)) {
- stubws->sessions = iter->next;
- afb_session_unref(iter->session);
- free(iter);
+ s = stubws->sessions;
+ stubws->sessions = NULL;
+ while(s) {
+ n = s->next;
+ afb_session_unref(s->session);
+ free(s);
+ s = n;
}
}
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);
{
struct afb_stub_ws *stubws = closure;
+ afb_stub_ws_addref(stubws);
if (stubws->on_hangup)
stubws->on_hangup(stubws);
- release_sessions(stubws);
+ release_all_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;
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;
}
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;
{
if (!__atomic_sub_fetch(&stubws->refcount, 1, __ATOMIC_RELAXED)) {
drop_all_events(stubws);
- afb_evt_listener_unref(stubws->listener);
- release_sessions(stubws);
+ if (stubws->listener)
+ afb_evt_listener_unref(stubws->listener);
+ release_all_sessions(stubws);
afb_proto_ws_unref(stubws->proto);
afb_cred_unref(stubws->cred);
afb_apiset_unref(stubws->apiset);