int async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) { struct uwsgi_async_fd *last_uad = NULL, *uad = wsgi_req->waiting_fds; if (fd < 0) return -1; // find last slot while (uad) { last_uad = uad; uad = uad->next; } uad = uwsgi_malloc(sizeof(struct uwsgi_async_fd)); uad->fd = fd; uad->event = event_queue_write(); uad->prev = last_uad; uad->next = NULL; if (last_uad) { last_uad->next = uad; } else { wsgi_req->waiting_fds = uad; } if (timeout > 0) { async_add_timeout(wsgi_req, timeout); } uwsgi.async_waiting_fd_table[fd] = wsgi_req; wsgi_req->async_force_again = 1; return event_queue_add_fd_write(uwsgi.async_queue, fd); }
static int u_offload_pipe_do(struct uwsgi_thread *ut, struct uwsgi_offload_request *uor, int fd) { ssize_t rlen; // setup if (fd == -1) { event_queue_add_fd_read(ut->queue, uor->fd); return 0; } switch(uor->status) { // read event from fd case 0: if (!uor->buf) { uor->buf = uwsgi_malloc(4096); } rlen = read(uor->fd, uor->buf, 4096); if (rlen > 0) { uor->to_write = rlen; uor->pos = 0; if (event_queue_del_fd(ut->queue, uor->fd, event_queue_read())) return -1; if (event_queue_add_fd_write(ut->queue, uor->s)) return -1; uor->status = 1; return 0; } if (rlen < 0) { uwsgi_offload_retry uwsgi_error("u_offload_pipe_do() -> read()"); } return -1; // write event on s case 1: rlen = write(uor->s, uor->buf + uor->pos, uor->to_write); if (rlen > 0) { uor->to_write -= rlen; uor->pos += rlen; if (uor->to_write == 0) { if (event_queue_del_fd(ut->queue, uor->s, event_queue_write())) return -1; if (event_queue_add_fd_read(ut->queue, uor->fd)) return -1; uor->status = 0; } return 0; } else if (rlen < 0) { uwsgi_offload_retry uwsgi_error("u_offload_pipe_do() -> write()"); } return -1; default: break; } return -1; }
int uwsgi_cr_hook_instance_write(struct corerouter_session *cs, ssize_t (*hook)(struct corerouter_session *)) { struct uwsgi_corerouter *ucr = cs->corerouter; // first check the case of event removal if (hook == NULL) { // nothing changed if (!cs->event_hook_instance_write) goto unchanged; // if there is a read event defined, le'ts modify it if (cs->event_hook_instance_read) { #ifdef UWSGI_DEBUG uwsgi_log("event_queue_fd_readwrite_to_read() for %d\n", cs->instance_fd); #endif if (event_queue_fd_readwrite_to_read(ucr->queue, cs->instance_fd)) return -1; } // simply remove the write event else { #ifdef UWSGI_DEBUG uwsgi_log("event_queue_del_fd() for %d\n", cs->instance_fd); #endif if (event_queue_del_fd(ucr->queue, cs->instance_fd, event_queue_write())) return -1; } } else { // set the hook // if read is not defined, simply add a single monitor if (cs->event_hook_instance_read == NULL) { if (!cs->event_hook_instance_write) { #ifdef UWSGI_DEBUG uwsgi_log("event_queue_add_fd_write() for %d\n", cs->instance_fd); #endif if (event_queue_add_fd_write(ucr->queue, cs->instance_fd)) return -1; } } else { if (!cs->event_hook_instance_write) { #ifdef UWSGI_DEBUG uwsgi_log("event_queue_fd_read_to_readwrite() for %d\n", cs->instance_fd); #endif if (event_queue_fd_read_to_readwrite(ucr->queue, cs->instance_fd)) return -1; } } } unchanged: #ifdef UWSGI_DEBUG uwsgi_log("event_hook_instance_write set to %p for %d\n", hook, cs->instance_fd); #endif cs->event_hook_instance_write = hook; return 0; }
int uwsgi_cr_set_hooks(struct corerouter_peer *peer, ssize_t (*read_hook)(struct corerouter_peer *), ssize_t (*write_hook)(struct corerouter_peer *)) { struct corerouter_session *cs = peer->session; struct uwsgi_corerouter *ucr = cs->corerouter; //uwsgi_log("uwsgi_cr_set_hooks(%d, %p, %p)\n", peer->fd, read_hook, write_hook); if (read_hook) { peer->last_hook_read = read_hook; } if (write_hook) { peer->last_hook_write = write_hook; } int read_changed = 1; int write_changed = 1; if (read_hook && peer->hook_read) { read_changed = 0; } else if (!read_hook && !peer->hook_read) { read_changed = 0; } if (write_hook && peer->hook_write) { write_changed = 0; } else if (!write_hook && !peer->hook_write) { write_changed = 0; } if (!read_changed && !write_changed) { goto unchanged; } int has_read = 0; int has_write = 0; if (peer->hook_read) { has_read = 1; } if (peer->hook_write) { has_write = 1; } if (!read_hook && !write_hook) { if (has_read) { if (event_queue_del_fd(ucr->queue, peer->fd, event_queue_read())) return -1; } if (has_write) { if (event_queue_del_fd(ucr->queue, peer->fd, event_queue_write())) return -1; } } else if (read_hook && write_hook) { if (has_read) { if (event_queue_fd_read_to_readwrite(ucr->queue, peer->fd)) return -1; } else if (has_write) { if (event_queue_fd_write_to_readwrite(ucr->queue, peer->fd)) return -1; } } else if (read_hook) { if (has_write) { if (write_changed) { if (event_queue_fd_write_to_read(ucr->queue, peer->fd)) return -1; } else { if (event_queue_fd_write_to_readwrite(ucr->queue, peer->fd)) return -1; } } else { if (event_queue_add_fd_read(ucr->queue, peer->fd)) return -1; } } else if (write_hook) { if (has_read) { if (read_changed) { if (event_queue_fd_read_to_write(ucr->queue, peer->fd)) return -1; } else { if (event_queue_fd_read_to_readwrite(ucr->queue, peer->fd)) return -1; } } else { if (event_queue_add_fd_write(ucr->queue, peer->fd)) return -1; } } unchanged: peer->hook_read = read_hook; peer->hook_write = write_hook; return 0; }