diff options
author | José Bollo <jose.bollo@iot.bzh> | 2018-02-22 13:22:48 +0100 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2018-02-22 13:22:48 +0100 |
commit | ca820c65c2b03a24e8936218171c6c1d138fd1f7 (patch) | |
tree | f7e31ea8e63d3321af64226e360a78c504a09bb3 /src/afb-api-ws.c | |
parent | f15ea770dd9b13a20331853a026091316984f9ca (diff) |
fdev: Introduce fdev for file event handling
This is an effort to keep cutting dependency to systemd.
Change-Id: I9a0c032a1095e297c7f3ac5b67827fda3658b8d9
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'src/afb-api-ws.c')
-rw-r--r-- | src/afb-api-ws.c | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/src/afb-api-ws.c b/src/afb-api-ws.c index 7fbe5be1..489b43b1 100644 --- a/src/afb-api-ws.c +++ b/src/afb-api-ws.c @@ -30,19 +30,19 @@ #include <sys/socket.h> #include <sys/un.h> -#include <systemd/sd-event.h> +#include "afb-fdev.h" +#include "afb-systemd.h" #include "afb-api.h" #include "afb-apiset.h" -#include "afb-systemd.h" #include "afb-stub-ws.h" #include "verbose.h" +#include "fdev.h" struct api_ws { char *path; /* path of the object for the API */ char *api; /* api name of the interface */ - int fd; /* file descriptor */ - sd_event_source *listensrc; /**< systemd source for server socket */ + struct fdev *fdev; /* fdev handler */ struct afb_apiset *apiset; }; @@ -77,7 +77,6 @@ static struct api_ws *api_ws_make(const char *path) goto error2; } - api->fd = -1; return api; error2: @@ -176,7 +175,7 @@ static int api_ws_socket(const char *path, int server) /* check for systemd socket */ if (0 == strncmp(path, "sd:", 3)) - fd = systemd_fds_for(path + 3); + fd = afb_systemd_fds_for(path + 3); else { /* check for unix socket */ if (0 == strncmp(path, "unix:", 5)) @@ -200,6 +199,24 @@ static int api_ws_socket(const char *path, int server) return fd; } +static struct fdev *api_ws_socket_fdev(const char *path, int server) +{ + int fd; + struct fdev *fdev; + + fd = api_ws_socket(path, server); + if (fd < 0) + fdev = 0; + else { + fdev = afb_fdev_create(fd); + if (!fdev) + close(fd); + } + if (!fdev) + ERROR("can't make %s socket for %s", server ? "server" : "client", path); + return fdev; +} + /**********************************************************************************/ int afb_api_ws_add_client(const char *path, struct afb_apiset *apiset, int strong) @@ -213,27 +230,23 @@ int afb_api_ws_add_client(const char *path, struct afb_apiset *apiset, int stron goto error; /* connect to the service */ - apiws->fd = api_ws_socket(apiws->path, 0); - if (apiws->fd < 0) { - ERROR("can't connect to ws service %s", apiws->path); + apiws->fdev = api_ws_socket_fdev(apiws->path, 0); + if (!apiws->fdev) goto error2; - } - stubws = afb_stub_ws_create_client(apiws->fd, apiws->api, apiset); + stubws = afb_stub_ws_create_client(apiws->fdev, apiws->api, apiset); if (!stubws) { ERROR("can't setup client ws service to %s", apiws->path); goto error3; } if (afb_stub_ws_client_add(stubws, apiset) < 0) { ERROR("can't add the client to the apiset for service %s", apiws->path); - goto error4; + goto error3; } free(apiws); return 0; -error4: - afb_stub_ws_unref(stubws); error3: - close(apiws->fd); + afb_stub_ws_unref(stubws); error2: free(apiws); error: @@ -250,9 +263,9 @@ int afb_api_ws_add_client_weak(const char *path, struct afb_apiset *apiset) return afb_api_ws_add_client(path, apiset, 0); } -static int api_ws_server_accept_client(struct api_ws *apiws, int fd) +static int api_ws_server_accept_client(struct api_ws *apiws, struct fdev *fdev) { - return -!afb_stub_ws_create_server(fd, apiws->api, apiws->apiset); + return -!afb_stub_ws_create_server(fdev, apiws->api, apiws->apiset); } static void api_ws_server_accept(struct api_ws *apiws) @@ -260,20 +273,28 @@ static void api_ws_server_accept(struct api_ws *apiws) int rc, fd; struct sockaddr addr; socklen_t lenaddr; + struct fdev *fdev; lenaddr = (socklen_t)sizeof addr; - fd = accept(apiws->fd, &addr, &lenaddr); - if (fd >= 0) { - rc = api_ws_server_accept_client(apiws, fd); - if (rc >= 0) - return; - close(fd); + fd = accept(fdev_fd(apiws->fdev), &addr, &lenaddr); + if (fd < 0) { + ERROR("can't accept connection to %s: %m", apiws->path); + } else { + fdev = afb_fdev_create(fd); + if (!fdev) { + ERROR("can't hold accepted connection to %s: %m", apiws->path); + close(fd); + } else { + rc = api_ws_server_accept_client(apiws, fdev); + if (rc < 0) + ERROR("can't serve accepted connection to %s: %m", apiws->path); + } } } static int api_ws_server_connect(struct api_ws *apiws); -static int api_ws_server_listen_callback(sd_event_source *src, int fd, uint32_t revents, void *closure) +static void api_ws_server_listen_callback(void *closure, uint32_t revents, struct fdev *fdev) { struct api_ws *apiws = closure; @@ -281,42 +302,28 @@ static int api_ws_server_listen_callback(sd_event_source *src, int fd, uint32_t api_ws_server_accept(apiws); if ((revents & EPOLLHUP) != 0) api_ws_server_connect(apiws); - return 0; } static void api_ws_server_disconnect(struct api_ws *apiws) { - if (apiws->listensrc != NULL) { - sd_event_source_unref(apiws->listensrc); - apiws->listensrc = NULL; - } - if (apiws->fd >= 0) { - close(apiws->fd); - apiws->fd = -1; - } + fdev_unref(apiws->fdev); + apiws->fdev = 0; } static int api_ws_server_connect(struct api_ws *apiws) { - int rc; - /* ensure disconnected */ api_ws_server_disconnect(apiws); /* request the service object name */ - apiws->fd = api_ws_socket(apiws->path, 1); - if (apiws->fd < 0) + apiws->fdev = api_ws_socket_fdev(apiws->path, 1); + if (!apiws->fdev) ERROR("can't create socket %s", apiws->path); else { /* listen for service */ - rc = sd_event_add_io(afb_systemd_get_event_loop(), - &apiws->listensrc, apiws->fd, EPOLLIN, - api_ws_server_listen_callback, apiws); - if (rc >= 0) - return 0; - close(apiws->fd); - errno = -rc; - ERROR("can't add ws object %s", apiws->path); + fdev_set_events(apiws->fdev, EPOLLIN); + fdev_set_callback(apiws->fdev, api_ws_server_listen_callback, apiws); + return 0; } return -1; } |