void Connection::PendingWriteBase::on_write(uv_write_t* req, int status) { PendingWrite* pending_write = static_cast<PendingWrite*>(req->data); Connection* connection = static_cast<Connection*>(pending_write->connection_); while (!pending_write->handlers_.is_empty()) { Handler* handler = pending_write->handlers_.front(); pending_write->handlers_.remove(handler); switch (handler->state()) { case Handler::REQUEST_STATE_WRITING: if (status == 0) { handler->set_state(Handler::REQUEST_STATE_READING); connection->pending_reads_.add_to_back(handler); } else { if (!connection->is_closing()) { connection->notify_error("Write error '" + std::string(UV_ERRSTR(status, connection->loop_)) + "'"); connection->defunct(); } connection->stream_manager_.release(handler->stream()); handler->stop_timer(); handler->set_state(Handler::REQUEST_STATE_DONE); handler->on_error(CASS_ERROR_LIB_WRITE_ERROR, "Unable to write to socket"); handler->dec_ref(); } break; case Handler::REQUEST_STATE_TIMEOUT_WRITE_OUTSTANDING: // The read may still come back, handle cleanup there handler->set_state(Handler::REQUEST_STATE_TIMEOUT); connection->pending_reads_.add_to_back(handler); break; case Handler::REQUEST_STATE_READ_BEFORE_WRITE: // The read callback happened before the write callback // returned. This is now responsible for cleanup. handler->stop_timer(); handler->set_state(Handler::REQUEST_STATE_DONE); handler->dec_ref(); break; case Handler::REQUEST_STATE_RETRY_WRITE_OUTSTANDING: handler->stop_timer(); handler->retry(); handler->dec_ref(); break; default: assert(false && "Invalid request state after write finished"); break; } } connection->pending_writes_size_ -= pending_write->size(); if (connection->pending_writes_size_ < connection->config_.write_bytes_low_water_mark() && connection->state_ == CONNECTION_STATE_OVERWHELMED) { connection->set_state(CONNECTION_STATE_READY); } connection->pending_writes_.remove(pending_write); delete pending_write; connection->flush(); }