Commit cf86c1e3 authored by Rusty Russell's avatar Rusty Russell

ccan/io: test read after hangup.

In particular, make sure that idle connections don't get closed.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent d0458a43
......@@ -31,8 +31,12 @@ static bool add_fd(struct fd *fd, short events)
max_fds = num;
}
pollfds[num_fds].fd = fd->fd;
pollfds[num_fds].events = events;
/* In case it's idle. */
if (!events)
pollfds[num_fds].fd = -fd->fd;
else
pollfds[num_fds].fd = fd->fd;
pollfds[num_fds].revents = 0; /* In case we're iterating now */
fds[num_fds] = fd;
fd->backend_info = num_fds;
......@@ -91,8 +95,11 @@ void backend_plan_changed(struct io_conn *conn)
assert(!mask || pfd->events != mask);
pfd->events |= mask;
}
if (pfd->events)
if (pfd->events) {
num_waiting++;
pfd->fd = conn->fd.fd;
} else
pfd->fd = -conn->fd.fd;
if (!conn->plan.next)
num_closing++;
......
#include <ccan/io/io.h>
/* Include the C files directly. */
#include <ccan/io/poll.c>
#include <ccan/io/io.c>
#include <ccan/tap/tap.h>
#include <sys/wait.h>
#include <stdio.h>
static int fds2[2];
static struct io_plan timeout_wakeup(struct io_conn *conn, char *buf)
{
/* This kills the dummy connection. */
close(fds2[1]);
return io_read(buf, 16, io_close, NULL);
}
int main(void)
{
int fds[2];
struct io_conn *conn;
char buf[16];
plan_tests(4);
ok1(pipe(fds) == 0);
/* Write then close. */
io_new_conn(fds[1], io_write("hello there world", 16, io_close, NULL),
NULL, NULL);
conn = io_new_conn(fds[0], io_idle(), NULL, NULL);
/* To avoid assert(num_waiting) */
ok1(pipe(fds2) == 0);
io_new_conn(fds2[0], io_read(buf, 16, io_close, NULL), NULL, NULL);
/* After half a second, it will read. */
io_timeout(conn, time_from_msec(500), timeout_wakeup, buf);
ok1(io_loop() == NULL);
ok1(memcmp(buf, "hello there world", 16) == 0);
/* This exits depending on whether all tests passed */
return exit_status();
}
#include <ccan/io/io.h>
/* Include the C files directly. */
#include <ccan/io/poll.c>
#include <ccan/io/io.c>
#include <ccan/tap/tap.h>
#include <sys/wait.h>
#include <stdio.h>
#include <signal.h>
static char inbuf[8];
static struct io_plan wake_it(struct io_conn *conn, struct io_conn *reader)
{
io_wake(reader, io_read(inbuf, 8, io_close, NULL));
return io_close(conn, NULL);
}
int main(void)
{
int fds[2];
struct io_conn *conn;
plan_tests(3);
ok1(pipe(fds) == 0);
conn = io_new_conn(fds[0], io_idle(), NULL, NULL);
io_new_conn(fds[1], io_write("EASYTEST", 8, wake_it, conn),
NULL, NULL);
ok1(io_loop() == NULL);
ok1(memcmp(inbuf, "EASYTEST", sizeof(inbuf)) == 0);
/* This exits depending on whether all tests passed */
return exit_status();
}
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