mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
ccan: update to fix io_wake bug.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
87ef7acbd6
commit
7f0d54533a
@ -1,3 +1,3 @@
|
||||
CCAN imported from http://ccodearchive.net.
|
||||
|
||||
CCAN version: init-2367-ged6dd33
|
||||
CCAN version: init-2380-gd00c9d1b
|
||||
|
@ -49,7 +49,7 @@ struct ripemd160_ctx {
|
||||
uint32_t s[5];
|
||||
uint64_t bytes;
|
||||
union {
|
||||
uint32_t u32[8];
|
||||
uint32_t u32[16];
|
||||
unsigned char u8[64];
|
||||
} buf;
|
||||
#endif
|
||||
|
@ -392,12 +392,25 @@ void io_ready(struct io_conn *conn, int pollflags)
|
||||
|
||||
void io_do_always(struct io_conn *conn)
|
||||
{
|
||||
/* There's a corner case where the in next_plan wakes up the
|
||||
* out, placing it in IO_ALWAYS and we end up processing it immediately,
|
||||
* only to leave it in the always list.
|
||||
*
|
||||
* Yet we can't just process one, in case they are both supposed
|
||||
* to be done, so grab state beforehand.
|
||||
*/
|
||||
bool always_out = (conn->plan[IO_OUT].status == IO_ALWAYS);
|
||||
|
||||
if (conn->plan[IO_IN].status == IO_ALWAYS)
|
||||
if (!next_plan(conn, &conn->plan[IO_IN]))
|
||||
return;
|
||||
|
||||
if (conn->plan[IO_OUT].status == IO_ALWAYS)
|
||||
if (always_out) {
|
||||
/* You can't *unalways* a conn (except by freeing, in which
|
||||
* case next_plan() returned false */
|
||||
assert(conn->plan[IO_OUT].status == IO_ALWAYS);
|
||||
next_plan(conn, &conn->plan[IO_OUT]);
|
||||
}
|
||||
}
|
||||
|
||||
void io_do_wakeup(struct io_conn *conn, enum io_direction dir)
|
||||
|
54
ccan/ccan/io/test/run-40-wakeup-mutual.c
Normal file
54
ccan/ccan/io/test/run-40-wakeup-mutual.c
Normal file
@ -0,0 +1,54 @@
|
||||
/* Test previous issue: in duplex case, we wake reader reader wakes writer. */
|
||||
#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 struct io_plan *block_reading(struct io_conn *conn, void *unused)
|
||||
{
|
||||
static char buf[1];
|
||||
return io_read(conn, buf, sizeof(buf), io_never, NULL);
|
||||
}
|
||||
|
||||
static struct io_plan *writer_woken(struct io_conn *conn, void *unused)
|
||||
{
|
||||
pass("Writer woken up");
|
||||
return io_write(conn, "1", 1, io_close_cb, NULL);
|
||||
}
|
||||
|
||||
static struct io_plan *reader_woken(struct io_conn *conn, void *unused)
|
||||
{
|
||||
pass("Reader woken up");
|
||||
/* Wake writer */
|
||||
io_wake(conn);
|
||||
return block_reading(conn, unused);
|
||||
}
|
||||
|
||||
static struct io_plan *setup_conn(struct io_conn *conn, void *trigger)
|
||||
{
|
||||
return io_duplex(conn,
|
||||
io_wait(conn, trigger, reader_woken, NULL),
|
||||
io_out_wait(conn, conn, writer_woken, NULL));
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fds[2];
|
||||
|
||||
plan_tests(3);
|
||||
ok1(socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) == 0);
|
||||
|
||||
/* We use 'fds' as pointer to wake writer. */
|
||||
io_new_conn(NULL, fds[0], setup_conn, fds);
|
||||
|
||||
io_wake(fds);
|
||||
io_loop(NULL, NULL);
|
||||
|
||||
close(fds[1]);
|
||||
|
||||
/* This exits depending on whether all tests passed */
|
||||
return exit_status();
|
||||
}
|
Loading…
Reference in New Issue
Block a user