Instead of assuming they want a connection made from the new fd, hand
the fd to a callback.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
13 files changed:
struct fd fd;
/* These are for connections we create. */
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;
void *io_loop_return;
struct io_listener *io_new_listener_(int fd,
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));
void *arg)
{
struct io_listener *l = malloc(sizeof(*l));
l->fd.listener = true;
l->fd.fd = 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;
if (!add_listener(l)) {
free(l);
return NULL;
/**
* io_new_listener - create a new accepting listener.
* @fd: the file descriptor.
/**
* 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).
*/
*
* Returns NULL on error (and sets errno).
*/
-#define io_new_listener(fd, start, finish, arg) \
+#define io_new_listener(fd, init, arg) \
- 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,
(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),
static void accept_conn(struct io_listener *l)
{
static void accept_conn(struct io_listener *l)
{
int fd = accept(l->fd.fd, NULL, NULL);
/* FIXME: What to do here? */
if (fd < 0)
return;
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;
- }
}
/* It's OK to miss some, as long as we make progress. */
}
/* It's OK to miss some, as long as we make progress. */
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)
{
int fd, on = 1;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
plan_tests(9);
fd = make_listen_fd("65001", &addrinfo);
ok1(fd >= 0);
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()) {
ok1(l);
fflush(stdout);
if (!fork()) {
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)
{
int fd, on = 1;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
d->state = 0;
fd = make_listen_fd("65002", &addrinfo);
ok1(fd >= 0);
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()) {
ok1(l);
fflush(stdout);
if (!fork()) {
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)
{
int fd, on = 1;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
d->state = 0;
fd = make_listen_fd("65003", &addrinfo);
ok1(fd >= 0);
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()) {
ok1(l);
fflush(stdout);
if (!fork()) {
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)
{
int fd, on = 1;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
memset(d->buf, 'a', d->bytes);
fd = make_listen_fd("65004", &addrinfo);
ok1(fd >= 0);
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()) {
ok1(l);
fflush(stdout);
if (!fork()) {
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)
{
int fd, on = 1;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
memset(d->buf, 'a', d->bytes);
fd = make_listen_fd("65005", &addrinfo);
ok1(fd >= 0);
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()) {
ok1(l);
fflush(stdout);
if (!fork()) {
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)
{
int fd, on = 1;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
d->state = 0;
fd = make_listen_fd("65006", &addrinfo);
ok1(fd >= 0);
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()) {
ok1(l);
fflush(stdout);
if (!fork()) {
+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;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
d->state = 0;
fd = make_listen_fd("65007", &addrinfo);
ok1(fd >= 0);
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()) {
ok1(l);
fflush(stdout);
if (!fork()) {
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)
{
int fd, on = 1;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
d->state = 0;
fd = make_listen_fd("65012", &addrinfo);
ok1(fd >= 0);
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()) {
ok1(d->l);
fflush(stdout);
if (!fork()) {
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)
{
int fd, on = 1;
static int make_listen_fd(const char *port, struct addrinfo **info)
{
int fd, on = 1;
d->timeout_usec = 100000;
fd = make_listen_fd("65002", &addrinfo);
ok1(fd >= 0);
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);