- set_current(conn);
- switch (conn->plan.io(conn->fd.fd, &conn->plan)) {
- case -1: /* Failure means a new plan: close up. */
- conn->plan = io_close();
- backend_plan_changed(conn);
- break;
- case 0: /* Keep going with plan. */
- break;
- case 1: /* Done: get next plan. */
- if (timeout_active(conn))
- backend_del_timeout(conn);
- /* In case they call io_duplex, clear our poll flags so
- * both sides don't seem to be both doing read or write
- * (See assert(!mask || pfd->events != mask) in poll.c) */
- conn->plan.pollflag = 0;
- conn->plan = conn->plan.next(conn, conn->plan.next_arg);
- backend_plan_changed(conn);
- }
- set_current(NULL);
-
- /* If it closed, close duplex if not already */
- if (!conn->plan.next && conn->duplex && conn->duplex->plan.next) {
- set_current(conn->duplex);
- conn->duplex->plan = io_close();
- backend_plan_changed(conn->duplex);
- set_current(NULL);
+ /* We shouldn't have polled for this event if this wasn't true! */
+ assert(plan->status == IO_POLLING);
+
+ switch (plan->io(conn->fd.fd, &plan->arg)) {
+ case -1:
+ io_close(conn);
+ return false;
+ case 0:
+ return true;
+ case 1:
+ return next_plan(conn, plan);
+ default:
+ /* IO should only return -1, 0 or 1 */
+ abort();