decouple channel and query structures
authorPavel Šimerda <psimerda@redhat.com>
Sun, 9 Feb 2014 13:55:17 +0000 (14:55 +0100)
committerPavel Šimerda <psimerda@redhat.com>
Mon, 10 Feb 2014 10:20:50 +0000 (11:20 +0100)
include/netresolve.h
lib/backend.c
lib/channel.c
lib/netresolve-backend.h
lib/netresolve-private.h
lib/socket.c
lib/utils.c
tests/test-async.c
tools/netconnect.c

index 1d034b5afda89192dd19ab1c7f3b77e34160b3f2..d48e61f00d6e024550dcc11d7a28c57993a0b5f7 100644 (file)
@@ -30,7 +30,7 @@
 
 /* Channels and queries */
 typedef struct netresolve_channel *netresolve_t;
-typedef struct netresolve_channel *netresolve_query_t;
+typedef struct netresolve_query *netresolve_query_t;
 
 netresolve_t netresolve_open(void);
 void netresolve_close(netresolve_t channel);
index 9a35829c67b394cc1a0625bc569bf7f2425c2195..b6621234b63420654f75b438e76861e204784b8d 100644 (file)
@@ -175,7 +175,7 @@ netresolve_backend_add_path(netresolve_query_t query,
 
        debug("added path: %s", netresolve_get_path_string(query, response->pathcount - 1));
 
-       if (query->callbacks.on_bind)
+       if (query->channel->callbacks.on_bind)
                netresolve_query_bind(query, response->pathcount - 1);
 }
 
@@ -251,21 +251,21 @@ netresolve_backend_finished(netresolve_query_t query)
        /* Restart with the next *mandatory* backend. */
        while (*++query->backend) {
                if ((*query->backend)->mandatory) {
-                       netresolve_start(query);
+                       netresolve_query_start(query);
                        return;
                }
        }
 
-       if (query->callbacks.on_connect) {
+       if (query->channel->callbacks.on_connect) {
                netresolve_connect_start(query);
                return;
        }
 
-       netresolve_set_state(query, NETRESOLVE_STATE_FINISHED);
+       netresolve_query_set_state(query, NETRESOLVE_STATE_FINISHED);
        return;
 
 fail:
-       netresolve_set_state(query, NETRESOLVE_STATE_FAILED);
+       netresolve_query_set_state(query, NETRESOLVE_STATE_FAILED);
 }
 
 void
@@ -283,12 +283,12 @@ netresolve_backend_failed(netresolve_query_t query)
 
        /* Restart with the next backend. */
        if (*++query->backend) {
-               netresolve_start(query);
+               netresolve_query_start(query);
                return;
        }
 
 fail:
-       netresolve_set_state(query, NETRESOLVE_STATE_FAILED);
+       netresolve_query_set_state(query, NETRESOLVE_STATE_FAILED);
 }
 
 bool
index bec2414ba88eeaaadbb92cd5c4d30b599ce4b38c..a5bd9bba75a3345c1a75714fd0ef6a2279e34d28 100644 (file)
@@ -42,19 +42,15 @@ netresolve_t
 netresolve_open(void)
 {
        netresolve_t channel = calloc(1, sizeof *channel);
-
        if (!channel)
                return NULL;
 
-       channel->channel = channel;
        channel->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
        if (channel->epoll_fd == -1) {
                free(channel);
                return NULL;
        }
 
-       channel->first_connect_timeout = -1;
-
        channel->request.default_loopback = strtob(secure_getenv("NETRESOLVE_FLAG_DEFAULT_LOOPBACK"));
 
        return channel;
@@ -65,7 +61,11 @@ netresolve_close(netresolve_t channel)
 {
        if (!channel)
                return;
-       netresolve_set_state(channel, NETRESOLVE_STATE_INIT);
+
+       /* TODO: Loop through queries when they're decoupled from the channel. */
+       if (channel->query)
+               netresolve_query_done(channel->query);
+
        netresolve_set_backend_string(channel, "");
        close(channel->epoll_fd);
        memset(channel, 0, sizeof *channel);
@@ -91,20 +91,20 @@ state_to_string(enum netresolve_state state)
 }
 
 void
-netresolve_set_state(netresolve_t channel, enum netresolve_state state)
+netresolve_query_set_state(netresolve_query_t query, enum netresolve_state state)
 {
-       enum netresolve_state old_state = channel->state;
+       enum netresolve_state old_state = query->state;
 
-       channel->state = state;
+       query->state = state;
 
        debug("state: %s -> %s\n", state_to_string(old_state), state_to_string(state));
 
        /* Leaving state... */
        switch (old_state) {
        case NETRESOLVE_STATE_WAITING:
-               if (channel->callbacks.watch_fd)
-                       channel->callbacks.watch_fd(channel, channel->epoll_fd, 0,
-                                       channel->callbacks.user_data_fd);
+               if (query->channel->callbacks.watch_fd)
+                       query->channel->callbacks.watch_fd(query, query->channel->epoll_fd, 0,
+                                       query->channel->callbacks.user_data_fd);
                break;
        default:
                break;
@@ -113,47 +113,47 @@ netresolve_set_state(netresolve_t channel, enum netresolve_state state)
        /* Entering state... */
        switch (state) {
        case NETRESOLVE_STATE_INIT:
-               free(channel->response.paths);
-               free(channel->response.canonname);
-               memset(&channel->response, 0, sizeof channel->response);
+               free(query->response.paths);
+               free(query->response.canonname);
+               memset(&query->response, 0, sizeof query->response);
                break;
        case NETRESOLVE_STATE_WAITING:
-               if (channel->callbacks.watch_fd)
-                       channel->callbacks.watch_fd(channel, channel->epoll_fd, POLLIN,
-                                       channel->callbacks.user_data_fd);
-               netresolve_start(channel);
+               if (query->channel->callbacks.watch_fd)
+                       query->channel->callbacks.watch_fd(query, query->channel->epoll_fd, POLLIN,
+                                       query->channel->callbacks.user_data_fd);
+               netresolve_query_start(query);
                break;
        case NETRESOLVE_STATE_FINISHED:
-               if (channel->callbacks.on_connect)
-                       netresolve_connect_cleanup(channel);
-               if (channel->callbacks.on_success)
-                       channel->callbacks.on_success(channel, channel->callbacks.user_data);
+               if (query->channel->callbacks.on_connect)
+                       netresolve_connect_cleanup(query);
+               if (query->channel->callbacks.on_success)
+                       query->channel->callbacks.on_success(query, query->channel->callbacks.user_data);
                break;
        case NETRESOLVE_STATE_FAILED:
-               if (channel->callbacks.on_success)
-                       channel->callbacks.on_success(channel, channel->callbacks.user_data);
+               if (query->channel->callbacks.on_success)
+                       query->channel->callbacks.on_success(query, query->channel->callbacks.user_data);
                break;
        }
 }
 
 void
-netresolve_start(netresolve_t channel)
+netresolve_query_start(netresolve_query_t query)
 {
-       struct netresolve_backend *backend = *channel->backend;
+       struct netresolve_backend *backend = *query->backend;
 
-       backend->start(channel, backend->settings+1);
+       backend->start(query, backend->settings+1);
 }
 
 static bool
 dispatch_fd(netresolve_t channel, int fd, int events)
 {
-       struct netresolve_backend *backend = *channel->backend;
+       struct netresolve_backend *backend = *channel->query->backend;
 
-       if (!backend && netresolve_connect_dispatch(channel, fd, events))
+       if (!backend && netresolve_connect_dispatch(channel->query, fd, events))
                return true;
 
        if (backend && backend->dispatch) {
-               backend->dispatch(channel, fd, events);
+               backend->dispatch(channel->query, fd, events);
                return true;
        }
 
@@ -170,16 +170,16 @@ netresolve_epoll(netresolve_t channel, int timeout)
 
        /* Sanity check number of descriptors. */
        if (channel->epoll_count <= 0) {
-               netresolve_set_state(channel, NETRESOLVE_STATE_FAILED);
+               netresolve_query_set_state(channel->query, NETRESOLVE_STATE_FAILED);
                return;
        }
 
        nevents = epoll_wait(channel->epoll_fd, events, maxevents, channel->callbacks.watch_fd ? 0 : -1);
        if (nevents == -1) {
-               netresolve_set_state(channel, NETRESOLVE_STATE_FAILED);
+               netresolve_query_set_state(channel->query, NETRESOLVE_STATE_FAILED);
                return;
        }
-       for (i = 0; channel->state == NETRESOLVE_STATE_WAITING && i < nevents; i++)
+       for (i = 0; channel->query->state == NETRESOLVE_STATE_WAITING && i < nevents; i++)
                dispatch_fd(channel, events[i].data.fd, events[i].events);
 }
 
@@ -190,7 +190,7 @@ netresolve_watch_fd(netresolve_t channel, int fd, int events)
 
        debug("watching file descriptor: %d %d\n", fd, events);
 
-       if (!channel->backend || channel->epoll_fd == -1)
+       if (!channel->query->backend || channel->epoll_fd == -1)
                abort();
 
        if (epoll_ctl(channel->epoll_fd, EPOLL_CTL_DEL, fd, &event) != -1)
@@ -253,31 +253,38 @@ state_to_errno(enum netresolve_state state)
 netresolve_query_t
 netresolve_query(netresolve_t channel, const char *node, const char *service)
 {
-       if (channel->state == NETRESOLVE_STATE_WAITING) {
-               errno = EBUSY;
-               return NULL;
-       }
-       netresolve_set_state(channel, NETRESOLVE_STATE_INIT);
        if (!channel->backends)
                netresolve_set_backend_string(channel, secure_getenv("NETRESOLVE_BACKENDS"));
        if (!channel->backends) {
                errno = ENODATA;
                return NULL;
        }
-       channel->backend = channel->backends;
 
-       channel->request.node = node;
-       channel->request.service = service;
+        /* TODO: A list of queries will be used. */
+       if (channel->query)
+               return NULL;
+       channel->query = calloc(1, sizeof *channel->query);
+       if (!channel->query)
+               return NULL;
+       channel->query->channel = channel;
+       channel->query->first_connect_timeout = -1;
+
+       netresolve_query_set_state(channel->query, NETRESOLVE_STATE_INIT);
+       channel->query->backend = channel->backends;
 
-       netresolve_set_state(channel, NETRESOLVE_STATE_WAITING);
+       memcpy(&channel->query->request, &channel->request, sizeof channel->request);
+       channel->query->request.node = node;
+       channel->query->request.service = service;
+
+       netresolve_query_set_state(channel->query, NETRESOLVE_STATE_WAITING);
 
        /* Blocking mode. */
        if (!channel->callbacks.watch_fd)
-               while (channel->state == NETRESOLVE_STATE_WAITING)
+               while (channel->query->state == NETRESOLVE_STATE_WAITING)
                        netresolve_epoll(channel, -1);
 
-       errno = state_to_errno(channel->state);
-       return channel;
+       errno = state_to_errno(channel->query->state);
+       return channel->query;
 }
 
 bool
@@ -306,5 +313,9 @@ netresolve_dispatch_fd(netresolve_t channel, int fd, int events)
 void
 netresolve_query_done(netresolve_query_t query)
 {
-       netresolve_set_state(query, NETRESOLVE_STATE_INIT);
+       netresolve_query_set_state(query, NETRESOLVE_STATE_INIT);
+
+       /* TODO: Will be removed propery from a query list. */
+       query->channel->query = NULL;
+       free(query);
 }
index 0a186b9b980505e0903dad57ccc563590d6b4c0a..52d30115f8072836ecb3fbe6c1a8161342836644 100644 (file)
@@ -33,7 +33,7 @@
 #include <netdb.h>
 #include <poll.h>
 
-typedef struct netresolve_channel *netresolve_query_t;
+typedef struct netresolve_query *netresolve_query_t;
 
 /* Input */
 const char *netresolve_backend_get_node(netresolve_query_t query);
index 13b4994db649110d5761221a986a2213ee9f2396..b4679be8a9f8be81676b132b198e39fa6ecac8ab 100644 (file)
@@ -43,9 +43,9 @@ struct netresolve_backend {
        bool mandatory;
        char **settings;
        void *dl_handle;
-       void (*start)(netresolve_t channel, char **settings);
-       void (*dispatch)(netresolve_t channel, int fd, int revents);
-       void (*cleanup)(netresolve_t channel);
+       void (*start)(netresolve_query_t query, char **settings);
+       void (*dispatch)(netresolve_query_t query, int fd, int revents);
+       void (*cleanup)(netresolve_query_t query);
        void *data;
 };
 
@@ -74,13 +74,10 @@ struct netresolve_path {
 };
 
 struct netresolve_channel {
-       struct netresolve_channel *channel;
        int log_level;
-       enum netresolve_state state;
        int epoll_fd;
        int epoll_count;
-       struct netresolve_backend **backends, **backend;
-       int first_connect_timeout;
+       struct netresolve_backend **backends;
        struct {
                netresolve_callback_t on_success;
                netresolve_callback_t on_failure;
@@ -110,6 +107,16 @@ struct netresolve_channel {
                bool default_loopback;
                bool dns_srv_lookup;
        } request;
+       /* TODO: A list of queries will be used. */
+       struct netresolve_query *query;
+};
+
+struct netresolve_query {
+       struct netresolve_channel *channel;
+       enum netresolve_state state;
+       int first_connect_timeout;
+       struct netresolve_backend **backend;
+       struct netresolve_request request;
        struct netresolve_response {
                struct netresolve_path *paths;
                size_t pathcount;
@@ -124,20 +131,20 @@ struct netresolve_channel {
        char buffer[1024];
 };
 
-void netresolve_set_state(netresolve_t channel, enum netresolve_state state);
+void netresolve_query_set_state(netresolve_query_t query, enum netresolve_state state);
 
-void netresolve_start(netresolve_t channel);
+void netresolve_query_start(netresolve_query_t channel);
 void netresolve_epoll(netresolve_t channel, int timeout);
 void netresolve_watch_fd(netresolve_t channel, int fd, int events);
 int netresolve_add_timeout(netresolve_t channel, time_t sec, long nsec);
 void netresolve_remove_timeout(netresolve_t channel, int fd);
 
-void netresolve_query_bind(netresolve_t query, size_t idx);
-void netresolve_query_connect(netresolve_t query, size_t idx);
+void netresolve_query_bind(netresolve_query_t query, size_t idx);
+void netresolve_query_connect(netresolve_query_t query, size_t idx);
 
-void netresolve_connect_start(netresolve_t channel);
-bool netresolve_connect_dispatch(netresolve_t channel, int fd, int events);
-void netresolve_connect_cleanup(netresolve_t channel);
+void netresolve_connect_start(netresolve_query_t query);
+bool netresolve_connect_dispatch(netresolve_query_t query, int fd, int events);
+void netresolve_connect_cleanup(netresolve_query_t query);
 
 void netresolve_get_service_info(void (*callback)(int, int, int, void *), void *user_data,
                const char *request_service, int socktype, int protocol);
index 601c12a7df8fb040b9703cceec614bb26ecef47c..99f8e819067f2ee5a69cce55d6d84e0446d5bf76 100644 (file)
@@ -48,7 +48,7 @@ netresolve_query_bind(netresolve_query_t query, size_t idx)
                return;
        }
 
-       query->callbacks.on_bind(query, idx, sock, query->callbacks.user_data_sock);
+       query->channel->callbacks.on_bind(query, idx, sock, query->channel->callbacks.user_data_sock);
 }
 
 void
@@ -73,7 +73,7 @@ netresolve_query_connect(netresolve_query_t query, size_t idx)
        if (connect(path->socket.fd, sa, salen) == -1 && errno != EINPROGRESS)
                goto fail_connect;
 
-       netresolve_watch_fd(query, path->socket.fd, POLLOUT);
+       netresolve_watch_fd(query->channel, path->socket.fd, POLLOUT);
        path->socket.state = NETRESOLVE_STATE_WAITING;
        return;
 
@@ -96,9 +96,9 @@ connect_check(netresolve_query_t query)
                        break;
 
                if (path->socket.state == NETRESOLVE_STATE_FINISHED) {
-                       query->callbacks.on_connect(query, idx, path->socket.fd, query->callbacks.user_data_sock);
+                       query->channel->callbacks.on_connect(query, idx, path->socket.fd, query->channel->callbacks.user_data_sock);
                        path->socket.state = NETRESOLVE_STATE_INIT;
-                       netresolve_set_state(query, NETRESOLVE_STATE_FINISHED);
+                       netresolve_query_set_state(query, NETRESOLVE_STATE_FINISHED);
                        break;
                }
        }
@@ -110,7 +110,7 @@ connect_finished(netresolve_query_t query, struct netresolve_path *path)
        path->socket.state = NETRESOLVE_STATE_FINISHED;
 
        if (query->first_connect_timeout == -1)
-               query->first_connect_timeout = netresolve_add_timeout(query, FIRST_CONNECT_TIMEOUT, 0);
+               query->first_connect_timeout = netresolve_add_timeout(query->channel, FIRST_CONNECT_TIMEOUT, 0);
 
        connect_check(query);
 }
@@ -164,7 +164,7 @@ netresolve_connect_dispatch(netresolve_query_t query, int fd, int events)
                struct netresolve_path *path = &query->response.paths[i];
 
                if (fd == path->socket.fd) {
-                       netresolve_watch_fd(query, path->socket.fd, 0);
+                       netresolve_watch_fd(query->channel, path->socket.fd, 0);
 
                        if (events & POLLOUT) {
                                socklen_t len = sizeof(errno);
@@ -225,7 +225,7 @@ netresolve_connect_cleanup(netresolve_query_t query)
        }
 
        if (query->first_connect_timeout != -1) {
-               netresolve_remove_timeout(query, query->first_connect_timeout);
+               netresolve_remove_timeout(query->channel, query->first_connect_timeout);
                query->first_connect_timeout = -1;
        }
 }
index 05b24f35b401949f5a165b87364abedfc64bbe00..049d3a9d6c0421e9919baeb00a7edd13279a60ce 100644 (file)
@@ -29,7 +29,7 @@
 #include <netresolve-utils.h>
 
 static void
-on_socket(netresolve_t channel, int idx, int sock, void *user_data)
+on_socket(netresolve_query_t query, int idx, int sock, void *user_data)
 {
        int *psock = user_data;
 
index 4e21882f9be026d1626490fa90745bb5e18fff5a..08e9158993f8a66be1fbcdc672e0c3b5ef5db100 100644 (file)
@@ -32,7 +32,7 @@
 #include <netresolve.h>
 
 static void
-watch_fd(netresolve_t channel, int fd, int events, void *user_data)
+watch_fd(netresolve_query_t query, int fd, int events, void *user_data)
 {
        int epoll_fd = *(int *) user_data;
 
index 41096f70f948d5d88a173a01a1c9273ff3e32272..066938488d273aa07c8002f14bdc57b9f1458bac 100644 (file)
@@ -64,7 +64,7 @@ read_and_write(int rfd, int wfd)
 }
 
 static void
-on_connect(netresolve_t channel, int idx, int sock, void *user_data)
+on_connect(netresolve_query_t channel, int idx, int sock, void *user_data)
 {
        *(int *) user_data = sock;
 }
This page took 0.075824 seconds and 5 git commands to generate.