X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fio%2Fio.h;h=eeb5e36ecdff0bfedd633b734cc2b380b92d8b2b;hb=HEAD;hp=a93c6ed49941580efc4741ca58687b062d63c472;hpb=580457bd3e4af60d5367412589d2aa1bb0289eed;p=ccan diff --git a/ccan/io/io.h b/ccan/io/io.h index a93c6ed4..5d084828 100644 --- a/ccan/io/io.h +++ b/ccan/io/io.h @@ -59,7 +59,7 @@ struct io_conn; io_new_conn_((ctx), (fd), \ typesafe_cb_preargs(struct io_plan *, void *, \ (init), (arg), \ - struct io_conn *conn), \ + struct io_conn *), \ (void *)(arg)) struct io_conn *io_new_conn_(const tal_t *ctx, int fd, @@ -113,6 +113,8 @@ void io_set_finish_(struct io_conn *conn, * (tal'ocated off @ctx) and pass that to init(). Note that if there is * an error on this file descriptor, it will be freed. * + * Note: if the accept fails (usually due to EMFILE), init() will be called + * wth * Returns NULL on error (and sets errno). * * Example: @@ -389,6 +391,39 @@ struct io_plan *io_out_always_(struct io_conn *conn, void *), void *arg); +/** + * io_sock_shutdown - start socket close process (flushes TCP sockets). + * @conn: the connection the plan is for + * + * Simply closing a TCP socket can lose data; unfortunately you should + * shutdown(SHUT_WR) and wait for the other side to see this and close. + * Of course, you also need to set a timer, in case it doesn't (you may + * already have some responsiveness timer, of course). + * + * On error, is equivalent to io_close(). + * + * Example: + * #include + * + * // Timer infra needs wrapper to contain extra data. + * struct timeout_timer { + * struct timer t; + * struct io_conn *conn; + * }; + * static struct timers timers; + * + * static struct io_plan *flush_and_close(struct io_conn *conn) + * { + * struct timeout_timer *timeout; + * // Freed if conn closes normally. + * timeout = tal(conn, struct timeout_timer); + * timeout->conn = conn; + * timer_addrel(&timers, &timeout->t, time_from_sec(5)); + * return io_sock_shutdown(conn); + * } + */ +struct io_plan *io_sock_shutdown(struct io_conn *conn); + /** * io_connect - create an asynchronous connection to a listening socket. * @conn: the connection that plan is for. @@ -734,9 +769,9 @@ bool io_flush_sync(struct io_conn *conn); * * This allows you to temporarily service only one (or several) fds. * For example, you might want to flush out one io_conn and not - * receive any new connections or read any otherninput. + * receive any new connections or read any other input. * - * Returns true of there any exclusive io_conn remain, otherwise false. + * Returns true if any exclusive io_conn remain, otherwise false. * (This is useful for checking your own logic: dangling exclusive io_conn * are dangerous!). */ @@ -781,4 +816,22 @@ struct timemono (*io_time_override(struct timemono (*now)(void)))(void); */ int (*io_poll_override(int (*poll)(struct pollfd *fds, nfds_t nfds, int timeout)))(struct pollfd *, nfds_t, int); +/** + * io_have_fd - do we own this file descriptor? + * @fd: the file descriptor. + * @listener: if non-NULL, set to true if it's a listening socket (io_listener). + * + * Returns NULL if we don't own it, otherwise a struct io_conn * or struct io_listener *. + */ +const void *io_have_fd(int fd, bool *listener); + +/** + * io_set_extended_errors - enable callbacks for errors. + * @state: true or false. + * + * Defaults false for compatibility. See io_new_conn for what this changes. + */ +void io_set_extended_errors(bool state); +bool io_get_extended_errors(void); + #endif /* CCAN_IO_H */