Browse Source

io: add io_is_idle().

Turns out to be useful for complex cases.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 12 years ago
parent
commit
1273379185
4 changed files with 24 additions and 5 deletions
  1. 5 0
      ccan/io/io.c
  2. 15 0
      ccan/io/io.h
  3. 2 1
      ccan/io/test/run-06-idle.c
  4. 2 4
      ccan/io/test/run-14-duplex-both-read.c

+ 5 - 0
ccan/io/io.c

@@ -418,6 +418,11 @@ struct io_plan io_idle_(void)
 	return plan;
 	return plan;
 }
 }
 
 
+bool io_is_idle(const struct io_conn *conn)
+{
+	return conn->plan.io == NULL;
+}
+
 void io_wake_(struct io_conn *conn, struct io_plan plan)
 void io_wake_(struct io_conn *conn, struct io_plan plan)
 
 
 {
 {

+ 15 - 0
ccan/io/io.h

@@ -431,6 +431,21 @@ struct io_conn *io_duplex_(struct io_conn *conn, struct io_plan plan);
 #define io_wake(conn, plan) (io_plan_no_debug(), io_wake_((conn), (plan)))
 #define io_wake(conn, plan) (io_plan_no_debug(), io_wake_((conn), (plan)))
 void io_wake_(struct io_conn *conn, struct io_plan plan);
 void io_wake_(struct io_conn *conn, struct io_plan plan);
 
 
+/**
+ * io_is_idle - is a connection idle?
+ *
+ * This can be useful for complex protocols, eg. where you want a connection
+ * to send something, so you queue it and wake it if it's idle.
+ *
+ * Example:
+ *	struct io_conn *sleeper;
+ *	sleeper = io_new_conn(open("/dev/null", O_RDONLY), io_idle());
+ *
+ *	assert(io_is_idle(sleeper));
+ *	io_wake(sleeper, io_write("junk", 4, io_close_cb, NULL));
+ */
+bool io_is_idle(const struct io_conn *conn);
+
 /**
 /**
  * io_break - return from io_loop()
  * io_break - return from io_loop()
  * @ret: non-NULL value to return from io_loop().
  * @ret: non-NULL value to return from io_loop().

+ 2 - 1
ccan/io/test/run-06-idle.c

@@ -29,6 +29,7 @@ static struct io_plan read_done(struct io_conn *conn, struct data *d)
 
 
 static void finish_waker(struct io_conn *conn, struct data *d)
 static void finish_waker(struct io_conn *conn, struct data *d)
 {
 {
+	ok1(io_is_idle(idler));
 	io_wake(idler, io_read(d->buf, sizeof(d->buf), read_done, d));
 	io_wake(idler, io_read(d->buf, sizeof(d->buf), read_done, d));
 	ok1(d->state == 1);
 	ok1(d->state == 1);
 	d->state++;
 	d->state++;
@@ -102,7 +103,7 @@ int main(void)
 	int fd, status;
 	int fd, status;
 
 
 	/* This is how many tests you plan to run */
 	/* This is how many tests you plan to run */
-	plan_tests(13);
+	plan_tests(14);
 	d->state = 0;
 	d->state = 0;
 	fd = make_listen_fd(PORT, &addrinfo);
 	fd = make_listen_fd(PORT, &addrinfo);
 	ok1(fd >= 0);
 	ok1(fd >= 0);

+ 2 - 4
ccan/io/test/run-14-duplex-both-read.c

@@ -12,8 +12,6 @@
 #define PORT "65014"
 #define PORT "65014"
 #endif
 #endif
 
 
-#define is_idle(conn) ((conn)->plan.io == NULL)
-
 struct data {
 struct data {
 	struct io_listener *l;
 	struct io_listener *l;
 	int state;
 	int state;
@@ -32,11 +30,11 @@ static struct io_plan end(struct io_conn *conn, struct data *d)
 	d->state++;
 	d->state++;
 
 
 	/* last one out closes. */
 	/* last one out closes. */
-	if (conn == d->c1 && is_idle(d->c2))
+	if (conn == d->c1 && io_is_idle(d->c2))
 		return io_close();
 		return io_close();
 
 
 	/* last one out closes. */
 	/* last one out closes. */
-	if (conn == d->c2 && is_idle(d->c1))
+	if (conn == d->c2 && io_is_idle(d->c1))
 		return io_close();
 		return io_close();
 
 
 	return io_idle();
 	return io_idle();