]> git.ozlabs.org Git - ccan/blobdiff - ccan/io/io.h
io: io_never for events that should never happen.
[ccan] / ccan / io / io.h
index 558a8769e1428355c254af670790d01f5ccda09e..478190f4d05b16def3f7eb481c2c8ecff334ee83 100644 (file)
@@ -39,7 +39,8 @@ struct io_conn *io_new_conn_(int fd, struct io_plan plan);
  *
  * @finish will be called when an I/O operation fails, or you call
  * io_close() on the connection.  errno will be set to the value
- * after the failed I/O, or at the call to io_close().
+ * after the failed I/O, or at the call to io_close().  The fd
+ * will be closed (unless a duplex) before @finish is called.
  *
  * Example:
  * static void finish(struct io_conn *conn, void *unused)
@@ -290,6 +291,29 @@ struct io_plan io_write_partial_(const void *data, size_t *len,
                                 struct io_plan (*cb)(struct io_conn *, void*),
                                 void *arg);
 
+/**
+ * io_always - plan to immediately call next callback.
+ * @cb: function to call.
+ * @arg: @cb argument
+ *
+ * Sometimes it's neater to plan a callback rather than call it directly;
+ * for example, if you only need to read data for one path and not another.
+ *
+ * Example:
+ * static void start_conn_with_nothing(int fd)
+ * {
+ *     // Silly example: close on next time around loop.
+ *     io_new_conn(fd, io_always(io_close_cb, NULL));
+ * }
+ */
+#define io_always(cb, arg)                                             \
+       io_debug(io_always_(typesafe_cb_preargs(struct io_plan, void *, \
+                                               (cb), (arg),            \
+                                               struct io_conn *),      \
+                           (arg)))
+struct io_plan io_always_(struct io_plan (*cb)(struct io_conn *, void *),
+                         void *arg);
+
 /**
  * io_connect - plan to connect to a listening socket.
  * @fd: file descriptor.
@@ -466,6 +490,21 @@ bool io_is_idle(const struct io_conn *conn);
 #define io_break(ret, plan) (io_plan_no_debug(), io_break_((ret), (plan)))
 struct io_plan io_break_(void *ret, struct io_plan plan);
 
+/**
+ * io_never - assert if callback is called.
+ *
+ * Sometimes you want to make it clear that a callback should never happen
+ * (eg. for io_break).  This will assert() if called.
+ *
+ * Example:
+ * static struct io_plan break_out(struct io_conn *conn, void *unused)
+ * {
+ *     // We won't ever return from io_break
+ *     return io_break(conn, io_never());
+ * }
+ */
+struct io_plan io_never(void);
+
 /* FIXME: io_recvfrom/io_sendto */
 
 /**