Commit f3c92802 authored by Rusty Russell's avatar Rusty Russell

io: use normal linked lists.

There seems to be a bug with the overloaded single-linked list.
Rewrite.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent ec8654d9
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <poll.h> #include <poll.h>
#include "io_plan.h" #include "io_plan.h"
#include <ccan/list/list.h>
struct fd { struct fd {
int fd; int fd;
...@@ -62,8 +63,8 @@ struct io_conn { ...@@ -62,8 +63,8 @@ struct io_conn {
/* For duplex to save. */ /* For duplex to save. */
bool debug_saved; bool debug_saved;
/* always or closing list. */ /* always and closing lists. */
struct io_conn *list; struct list_node always, closing;
void (*finish)(struct io_conn *, void *arg); void (*finish)(struct io_conn *, void *arg);
void *finish_arg; void *finish_arg;
......
...@@ -92,7 +92,8 @@ struct io_conn *io_new_conn_(const tal_t *ctx, int fd, ...@@ -92,7 +92,8 @@ struct io_conn *io_new_conn_(const tal_t *ctx, int fd,
conn->fd.fd = fd; conn->fd.fd = fd;
conn->finish = NULL; conn->finish = NULL;
conn->finish_arg = NULL; conn->finish_arg = NULL;
conn->list = NULL; list_node_init(&conn->always);
list_node_init(&conn->closing);
conn->debug = false; conn->debug = false;
if (!add_conn(conn)) if (!add_conn(conn))
......
...@@ -8,14 +8,14 @@ ...@@ -8,14 +8,14 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include <ccan/list/list.h>
#include <ccan/time/time.h> #include <ccan/time/time.h>
#include <ccan/timer/timer.h> #include <ccan/timer/timer.h>
static size_t num_fds = 0, max_fds = 0, num_waiting = 0; static size_t num_fds = 0, max_fds = 0, num_waiting = 0;
static struct pollfd *pollfds = NULL; static struct pollfd *pollfds = NULL;
static struct fd **fds = NULL; static struct fd **fds = NULL;
static struct io_conn *closing = NULL, *always = NULL; static LIST_HEAD(closing);
static LIST_HEAD(always);
static bool add_fd(struct fd *fd, short events) static bool add_fd(struct fd *fd, short events)
{ {
...@@ -96,31 +96,21 @@ bool add_listener(struct io_listener *l) ...@@ -96,31 +96,21 @@ bool add_listener(struct io_listener *l)
void remove_from_always(struct io_conn *conn) void remove_from_always(struct io_conn *conn)
{ {
struct io_conn **p = &always; list_del_init(&conn->always);
while (*p != conn)
p = &(*p)->list;
*p = conn->list;
} }
void backend_new_closing(struct io_conn *conn) void backend_new_closing(struct io_conn *conn)
{ {
/* Already on always list? Remove it. */ /* In case it's on always list, remove it. */
if (conn->list) list_del_init(&conn->always);
remove_from_always(conn); list_add_tail(&closing, &conn->closing);
conn->list = closing;
closing = conn;
} }
void backend_new_always(struct io_conn *conn) void backend_new_always(struct io_conn *conn)
{ {
/* May already be in always list (other plan), or closing. */ /* In case it's already in always list. */
if (!conn->list) { list_del(&conn->always);
conn->list = always; list_add_tail(&always, &conn->always);
always = conn;
}
} }
void backend_new_plan(struct io_conn *conn) void backend_new_plan(struct io_conn *conn)
...@@ -202,14 +192,12 @@ static void accept_conn(struct io_listener *l) ...@@ -202,14 +192,12 @@ static void accept_conn(struct io_listener *l)
static bool close_conns(void) static bool close_conns(void)
{ {
bool ret = false; bool ret = false;
struct io_conn *conn;
while (closing) { while ((conn = list_pop(&closing, struct io_conn, closing)) != NULL) {
struct io_conn *conn = closing;
assert(conn->plan[IO_IN].status == IO_CLOSING); assert(conn->plan[IO_IN].status == IO_CLOSING);
assert(conn->plan[IO_OUT].status == IO_CLOSING); assert(conn->plan[IO_OUT].status == IO_CLOSING);
closing = closing->list;
del_conn(conn); del_conn(conn);
ret = true; ret = true;
} }
...@@ -219,16 +207,14 @@ static bool close_conns(void) ...@@ -219,16 +207,14 @@ static bool close_conns(void)
static bool handle_always(void) static bool handle_always(void)
{ {
bool ret = false; bool ret = false;
struct io_conn *conn;
while (always) { while ((conn = list_pop(&always, struct io_conn, always)) != NULL) {
struct io_conn *conn = always;
assert(conn->plan[IO_IN].status == IO_ALWAYS assert(conn->plan[IO_IN].status == IO_ALWAYS
|| conn->plan[IO_OUT].status == IO_ALWAYS); || conn->plan[IO_OUT].status == IO_ALWAYS);
/* Remove from list, and mark it so it knows that. */ /* Re-initialize, for next time. */
always = always->list; list_node_init(&conn->always);
conn->list = NULL;
io_do_always(conn); io_do_always(conn);
ret = true; ret = true;
} }
......
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