Commit 737705f0 authored by Rusty Russell's avatar Rusty Russell

ccan/io: generic init function for listening connections.

Instead of assuming they want a connection made from the new fd, hand
the fd to a callback.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 733b09fa
......@@ -15,9 +15,8 @@ struct io_listener {
struct fd fd;
/* These are for connections we create. */
struct io_plan (*next)(struct io_conn *, void *arg);
void (*finish)(struct io_conn *, void *arg);
void *conn_arg;
void (*init)(int fd, void *arg);
void *arg;
};
struct io_timeout {
......
......@@ -13,9 +13,7 @@
void *io_loop_return;
struct io_listener *io_new_listener_(int fd,
struct io_plan (*start)(struct io_conn *,
void *arg),
void (*finish)(struct io_conn *, void *),
void (*init)(int fd, void *arg),
void *arg)
{
struct io_listener *l = malloc(sizeof(*l));
......@@ -25,9 +23,8 @@ struct io_listener *io_new_listener_(int fd,
l->fd.listener = true;
l->fd.fd = fd;
l->next = start;
l->finish = finish;
l->conn_arg = arg;
l->init = init;
l->arg = arg;
if (!add_listener(l)) {
free(l);
return NULL;
......
......@@ -93,28 +93,21 @@ struct io_conn *io_new_conn_(int fd,
/**
* io_new_listener - create a new accepting listener.
* @fd: the file descriptor.
* @start: the first function to call on new connections.
* @finish: the function to call when the connection is closed or fails.
* @arg: the argument to both @start and @finish.
* @init: the function to call for a new connection
* @arg: the argument to @init.
*
* When @fd becomes readable, we accept() and turn that fd into a new
* connection.
* When @fd becomes readable, we accept() and pass that fd to init().
*
* Returns NULL on error (and sets errno).
*/
#define io_new_listener(fd, start, finish, arg) \
#define io_new_listener(fd, init, arg) \
io_new_listener_((fd), \
typesafe_cb_preargs(struct io_plan, void *, \
(start), (arg), \
struct io_conn *), \
typesafe_cb_preargs(void, void *, (finish), \
(arg), struct io_conn *), \
typesafe_cb_preargs(void, void *, \
(init), (arg), \
int fd), \
(arg))
struct io_listener *io_new_listener_(int fd,
struct io_plan (*start)(struct io_conn *,
void *arg),
void (*finish)(struct io_conn *,
void *arg),
void (*init)(int fd, void *arg),
void *arg);
/**
......
......@@ -144,17 +144,12 @@ void backend_wakeup(struct io_conn *conn)
static void accept_conn(struct io_listener *l)
{
struct io_conn *c;
int fd = accept(l->fd.fd, NULL, NULL);
/* FIXME: What to do here? */
if (fd < 0)
return;
c = io_new_conn(fd, l->next, l->finish, l->conn_arg);
if (!c) {
close(fd);
return;
}
l->init(fd, l->arg);
}
/* It's OK to miss some, as long as we make progress. */
......
......@@ -20,6 +20,12 @@ static void finish_ok(struct io_conn *conn, int *state)
io_break(state + 1, NULL, NULL);
}
static void init_conn(int fd, int *state)
{
if (!io_new_conn(fd, start_ok, finish_ok, state))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -63,7 +69,7 @@ int main(void)
plan_tests(9);
fd = make_listen_fd("65001", &addrinfo);
ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, &state);
l = io_new_listener(fd, init_conn, &state);
ok1(l);
fflush(stdout);
if (!fork()) {
......
......@@ -25,6 +25,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL);
}
static void init_conn(int fd, struct data *d)
{
if (!io_new_conn(fd, start_ok, finish_ok, d))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -69,7 +75,7 @@ int main(void)
d->state = 0;
fd = make_listen_fd("65002", &addrinfo);
ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d);
l = io_new_listener(fd, init_conn, d);
ok1(l);
fflush(stdout);
if (!fork()) {
......
......@@ -27,6 +27,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL);
}
static void init_conn(int fd, struct data *d)
{
if (!io_new_conn(fd, start_ok, finish_ok, d))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -89,7 +95,7 @@ int main(void)
d->state = 0;
fd = make_listen_fd("65003", &addrinfo);
ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d);
l = io_new_listener(fd, init_conn, d);
ok1(l);
fflush(stdout);
if (!fork()) {
......
......@@ -26,6 +26,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL);
}
static void init_conn(int fd, struct data *d)
{
if (!io_new_conn(fd, start_ok, finish_ok, d))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -91,7 +97,7 @@ int main(void)
memset(d->buf, 'a', d->bytes);
fd = make_listen_fd("65004", &addrinfo);
ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d);
l = io_new_listener(fd, init_conn, d);
ok1(l);
fflush(stdout);
if (!fork()) {
......
......@@ -26,6 +26,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL);
}
static void init_conn(int fd, struct data *d)
{
if (!io_new_conn(fd, start_ok, finish_ok, d))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -94,7 +100,7 @@ int main(void)
memset(d->buf, 'a', d->bytes);
fd = make_listen_fd("65005", &addrinfo);
ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d);
l = io_new_listener(fd, init_conn, d);
ok1(l);
fflush(stdout);
if (!fork()) {
......
......@@ -61,6 +61,12 @@ static void finish_idle(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL);
}
static void init_conn(int fd, struct data *d)
{
if (!io_new_conn(fd, start_idle, finish_idle, d))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -105,7 +111,7 @@ int main(void)
d->state = 0;
fd = make_listen_fd("65006", &addrinfo);
ok1(fd >= 0);
l = io_new_listener(fd, start_idle, finish_idle, d);
l = io_new_listener(fd, init_conn, d);
ok1(l);
fflush(stdout);
if (!fork()) {
......
......@@ -31,6 +31,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
d->state++;
}
static void init_conn(int fd, struct data *d)
{
if (!io_new_conn(fd, start_break, finish_ok, d))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -75,7 +81,7 @@ int main(void)
d->state = 0;
fd = make_listen_fd("65007", &addrinfo);
ok1(fd >= 0);
l = io_new_listener(fd, start_break, finish_ok, d);
l = io_new_listener(fd, init_conn, d);
ok1(l);
fflush(stdout);
if (!fork()) {
......
......@@ -36,6 +36,12 @@ static struct io_plan start_ok(struct io_conn *conn, struct data *d)
return io_read(d->buf, sizeof(d->buf), io_close, d);
}
static void init_conn(int fd, struct data *d)
{
if (!io_new_conn(fd, start_ok, finish_ok, d))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -79,7 +85,7 @@ int main(void)
d->state = 0;
fd = make_listen_fd("65012", &addrinfo);
ok1(fd >= 0);
d->l = io_new_listener(fd, start_ok, finish_ok, d);
d->l = io_new_listener(fd, init_conn, d);
ok1(d->l);
fflush(stdout);
if (!fork()) {
......
......@@ -45,6 +45,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL);
}
static void init_conn(int fd, struct data *d)
{
if (!io_new_conn(fd, start_ok, finish_ok, d))
abort();
}
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
......@@ -91,7 +97,7 @@ int main(void)
d->timeout_usec = 100000;
fd = make_listen_fd("65002", &addrinfo);
ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d);
l = io_new_listener(fd, init_conn, d);
ok1(l);
fflush(stdout);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment