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 { ...@@ -15,9 +15,8 @@ struct io_listener {
struct fd fd; struct fd fd;
/* These are for connections we create. */ /* These are for connections we create. */
struct io_plan (*next)(struct io_conn *, void *arg); void (*init)(int fd, void *arg);
void (*finish)(struct io_conn *, void *arg); void *arg;
void *conn_arg;
}; };
struct io_timeout { struct io_timeout {
......
...@@ -13,9 +13,7 @@ ...@@ -13,9 +13,7 @@
void *io_loop_return; void *io_loop_return;
struct io_listener *io_new_listener_(int fd, struct io_listener *io_new_listener_(int fd,
struct io_plan (*start)(struct io_conn *, void (*init)(int fd, void *arg),
void *arg),
void (*finish)(struct io_conn *, void *),
void *arg) void *arg)
{ {
struct io_listener *l = malloc(sizeof(*l)); struct io_listener *l = malloc(sizeof(*l));
...@@ -25,9 +23,8 @@ struct io_listener *io_new_listener_(int fd, ...@@ -25,9 +23,8 @@ struct io_listener *io_new_listener_(int fd,
l->fd.listener = true; l->fd.listener = true;
l->fd.fd = fd; l->fd.fd = fd;
l->next = start; l->init = init;
l->finish = finish; l->arg = arg;
l->conn_arg = arg;
if (!add_listener(l)) { if (!add_listener(l)) {
free(l); free(l);
return NULL; return NULL;
......
...@@ -93,28 +93,21 @@ struct io_conn *io_new_conn_(int fd, ...@@ -93,28 +93,21 @@ struct io_conn *io_new_conn_(int fd,
/** /**
* io_new_listener - create a new accepting listener. * io_new_listener - create a new accepting listener.
* @fd: the file descriptor. * @fd: the file descriptor.
* @start: the first function to call on new connections. * @init: the function to call for a new connection
* @finish: the function to call when the connection is closed or fails. * @arg: the argument to @init.
* @arg: the argument to both @start and @finish.
* *
* When @fd becomes readable, we accept() and turn that fd into a new * When @fd becomes readable, we accept() and pass that fd to init().
* connection.
* *
* Returns NULL on error (and sets errno). * 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), \ io_new_listener_((fd), \
typesafe_cb_preargs(struct io_plan, void *, \ typesafe_cb_preargs(void, void *, \
(start), (arg), \ (init), (arg), \
struct io_conn *), \ int fd), \
typesafe_cb_preargs(void, void *, (finish), \
(arg), struct io_conn *), \
(arg)) (arg))
struct io_listener *io_new_listener_(int fd, struct io_listener *io_new_listener_(int fd,
struct io_plan (*start)(struct io_conn *, void (*init)(int fd, void *arg),
void *arg),
void (*finish)(struct io_conn *,
void *arg),
void *arg); void *arg);
/** /**
......
...@@ -144,17 +144,12 @@ void backend_wakeup(struct io_conn *conn) ...@@ -144,17 +144,12 @@ void backend_wakeup(struct io_conn *conn)
static void accept_conn(struct io_listener *l) static void accept_conn(struct io_listener *l)
{ {
struct io_conn *c;
int fd = accept(l->fd.fd, NULL, NULL); int fd = accept(l->fd.fd, NULL, NULL);
/* FIXME: What to do here? */ /* FIXME: What to do here? */
if (fd < 0) if (fd < 0)
return; return;
c = io_new_conn(fd, l->next, l->finish, l->conn_arg); l->init(fd, l->arg);
if (!c) {
close(fd);
return;
}
} }
/* It's OK to miss some, as long as we make progress. */ /* 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) ...@@ -20,6 +20,12 @@ static void finish_ok(struct io_conn *conn, int *state)
io_break(state + 1, NULL, NULL); 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -63,7 +69,7 @@ int main(void) ...@@ -63,7 +69,7 @@ int main(void)
plan_tests(9); plan_tests(9);
fd = make_listen_fd("65001", &addrinfo); fd = make_listen_fd("65001", &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, &state); l = io_new_listener(fd, init_conn, &state);
ok1(l); ok1(l);
fflush(stdout); fflush(stdout);
if (!fork()) { if (!fork()) {
......
...@@ -25,6 +25,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) ...@@ -25,6 +25,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL); 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -69,7 +75,7 @@ int main(void) ...@@ -69,7 +75,7 @@ int main(void)
d->state = 0; d->state = 0;
fd = make_listen_fd("65002", &addrinfo); fd = make_listen_fd("65002", &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d); l = io_new_listener(fd, init_conn, d);
ok1(l); ok1(l);
fflush(stdout); fflush(stdout);
if (!fork()) { if (!fork()) {
......
...@@ -27,6 +27,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) ...@@ -27,6 +27,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL); 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -89,7 +95,7 @@ int main(void) ...@@ -89,7 +95,7 @@ int main(void)
d->state = 0; d->state = 0;
fd = make_listen_fd("65003", &addrinfo); fd = make_listen_fd("65003", &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d); l = io_new_listener(fd, init_conn, d);
ok1(l); ok1(l);
fflush(stdout); fflush(stdout);
if (!fork()) { if (!fork()) {
......
...@@ -26,6 +26,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) ...@@ -26,6 +26,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL); 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -91,7 +97,7 @@ int main(void) ...@@ -91,7 +97,7 @@ int main(void)
memset(d->buf, 'a', d->bytes); memset(d->buf, 'a', d->bytes);
fd = make_listen_fd("65004", &addrinfo); fd = make_listen_fd("65004", &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d); l = io_new_listener(fd, init_conn, d);
ok1(l); ok1(l);
fflush(stdout); fflush(stdout);
if (!fork()) { if (!fork()) {
......
...@@ -26,6 +26,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) ...@@ -26,6 +26,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL); 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -94,7 +100,7 @@ int main(void) ...@@ -94,7 +100,7 @@ int main(void)
memset(d->buf, 'a', d->bytes); memset(d->buf, 'a', d->bytes);
fd = make_listen_fd("65005", &addrinfo); fd = make_listen_fd("65005", &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d); l = io_new_listener(fd, init_conn, d);
ok1(l); ok1(l);
fflush(stdout); fflush(stdout);
if (!fork()) { if (!fork()) {
......
...@@ -61,6 +61,12 @@ static void finish_idle(struct io_conn *conn, struct data *d) ...@@ -61,6 +61,12 @@ static void finish_idle(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL); 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -105,7 +111,7 @@ int main(void) ...@@ -105,7 +111,7 @@ int main(void)
d->state = 0; d->state = 0;
fd = make_listen_fd("65006", &addrinfo); fd = make_listen_fd("65006", &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
l = io_new_listener(fd, start_idle, finish_idle, d); l = io_new_listener(fd, init_conn, d);
ok1(l); ok1(l);
fflush(stdout); fflush(stdout);
if (!fork()) { if (!fork()) {
......
...@@ -31,6 +31,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) ...@@ -31,6 +31,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
d->state++; 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -75,7 +81,7 @@ int main(void) ...@@ -75,7 +81,7 @@ int main(void)
d->state = 0; d->state = 0;
fd = make_listen_fd("65007", &addrinfo); fd = make_listen_fd("65007", &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
l = io_new_listener(fd, start_break, finish_ok, d); l = io_new_listener(fd, init_conn, d);
ok1(l); ok1(l);
fflush(stdout); fflush(stdout);
if (!fork()) { if (!fork()) {
......
...@@ -36,6 +36,12 @@ static struct io_plan start_ok(struct io_conn *conn, struct data *d) ...@@ -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); 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -79,7 +85,7 @@ int main(void) ...@@ -79,7 +85,7 @@ int main(void)
d->state = 0; d->state = 0;
fd = make_listen_fd("65012", &addrinfo); fd = make_listen_fd("65012", &addrinfo);
ok1(fd >= 0); 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); ok1(d->l);
fflush(stdout); fflush(stdout);
if (!fork()) { if (!fork()) {
......
...@@ -45,6 +45,12 @@ static void finish_ok(struct io_conn *conn, struct data *d) ...@@ -45,6 +45,12 @@ static void finish_ok(struct io_conn *conn, struct data *d)
io_break(d, NULL, NULL); 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) static int make_listen_fd(const char *port, struct addrinfo **info)
{ {
int fd, on = 1; int fd, on = 1;
...@@ -91,7 +97,7 @@ int main(void) ...@@ -91,7 +97,7 @@ int main(void)
d->timeout_usec = 100000; d->timeout_usec = 100000;
fd = make_listen_fd("65002", &addrinfo); fd = make_listen_fd("65002", &addrinfo);
ok1(fd >= 0); ok1(fd >= 0);
l = io_new_listener(fd, start_ok, finish_ok, d); l = io_new_listener(fd, init_conn, d);
ok1(l); ok1(l);
fflush(stdout); 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