void acceptor::async_accept(stream_socket &target,event_handler const &h) { if(!dont_block(h)) return; async_acceptor::pointer acceptor(new async_acceptor( h, &target, this )); on_readable(acceptor); }
void stream_socket::async_read_some(mutable_buffer const &buffer,io_handler const &h) { if(!dont_block(h)) return; #ifdef BOOSTER_AIO_FORCE_POLL reader_some::pointer reader(new reader_some(h,buffer,this)); on_readable(reader); #else system::error_code e; size_t n = read_some(buffer,e); if(e && would_block(e)) { reader_some::pointer reader(new reader_some(h,buffer,this)); on_readable(reader); } else { io_binder::pointer binder(new io_binder( h,n,e )); get_io_service().post(binder); } #endif }
static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { GPR_TIMER_BEGIN("workqueue.on_readable", 0); grpc_workqueue *workqueue = arg; if (error != GRPC_ERROR_NONE) { /* HACK: let wakeup_fd code know that we stole the fd */ workqueue->wakeup_fd.read_fd = 0; grpc_wakeup_fd_destroy(&workqueue->wakeup_fd); grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, NULL, "destroy"); GPR_ASSERT(gpr_atm_no_barrier_load(&workqueue->state) == 0); gpr_free(workqueue); } else { error = grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd); gpr_mpscq_node *n = gpr_mpscq_pop(&workqueue->queue); if (error == GRPC_ERROR_NONE) { grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd, &workqueue->read_closure); } else { /* recurse to get error handling */ on_readable(exec_ctx, arg, error); } if (n == NULL) { /* try again - queue in an inconsistant state */ wakeup(exec_ctx, workqueue); } else { switch (gpr_atm_full_fetch_add(&workqueue->state, -2)) { case 3: // had one count, one unorphaned --> done, unorphaned break; case 2: // had one count, one orphaned --> done, orphaned workqueue_destroy(exec_ctx, workqueue); break; case 1: case 0: // these values are illegal - representing an already done or // deleted workqueue GPR_UNREACHABLE_CODE(break); default: // schedule a wakeup since there's more to do wakeup(exec_ctx, workqueue); } grpc_closure *cl = (grpc_closure *)n; grpc_error *clerr = cl->error; cl->cb(exec_ctx, cl->cb_arg, clerr); GRPC_ERROR_UNREF(clerr); } } GPR_TIMER_END("workqueue.on_readable", 0); }