struct conn * dnode_peer_conn(struct server *server) { struct server_pool *pool; struct conn *conn; pool = server->owner; //if (server->ns_conn_q < pool->peer_connections) { if (server->ns_conn_q < 1) { conn = conn_get_peer(server, false, pool->redis); if (is_conn_secured(pool, server)) { conn->dnode_secured = 1; conn->dnode_crypto_state = 0; //need to do a encryption handshake } return conn; } //ASSERT(server->ns_conn_q == pool->peer_connections); /* * Pick a server connection from the head of the queue and insert * it back into the tail of queue to maintain the lru order */ conn = TAILQ_FIRST(&server->s_conn_q); ASSERT(!conn->dnode_client && !conn->dnode_server); TAILQ_REMOVE(&server->s_conn_q, conn, conn_tqe); TAILQ_INSERT_TAIL(&server->s_conn_q, conn, conn_tqe); return conn; }
static rstatus_t dnode_accept(struct context *ctx, struct conn *p) { rstatus_t status; struct conn *c; int sd; ASSERT(p->dnode_server); ASSERT(p->sd > 0); ASSERT(p->recv_active && p->recv_ready); for (;;) { sd = accept(p->sd, NULL, NULL); if (sd < 0) { if (errno == EINTR) { log_debug(LOG_VERB, "dyn: accept on p %d not ready - eintr", p->sd); continue; } if (errno == EAGAIN || errno == EWOULDBLOCK) { log_debug(LOG_VERB, "dyn: accept on p %d not ready - eagain", p->sd); p->recv_ready = 0; return DN_OK; } /* * FIXME: On EMFILE or ENFILE mask out IN event on the proxy; mask * it back in when some existing connection gets closed */ log_error("dyn: accept on p %d failed: %s", p->sd, strerror(errno)); return DN_ERROR; } break; } log_debug(LOG_NOTICE, "dyn: accept on sd %d", sd); c = conn_get_peer(p->owner, true, p->redis); if (c == NULL) { log_error("dyn: get conn client peer for c %d from p %d failed: %s", sd, p->sd, strerror(errno)); status = close(sd); if (status < 0) { log_error("dyn: close c %d failed, ignored: %s", sd, strerror(errno)); } return DN_ENOMEM; } c->sd = sd; //fixme for dnode server stats //stats_pool_incr(ctx, c->owner, client_connections); status = dn_set_nonblocking(c->sd); if (status < 0) { log_error("dyn: set nonblock on c %d from p %d failed: %s", c->sd, p->sd, strerror(errno)); c->close(ctx, c); return status; } if (p->family == AF_INET || p->family == AF_INET6) { status = dn_set_tcpnodelay(c->sd); if (status < 0) { log_warn("dyn: set tcpnodelay on c %d from p %d failed, ignored: %s", c->sd, p->sd, strerror(errno)); } } status = event_add_conn(ctx->evb, c); if (status < 0) { log_error("dyn: event add conn from p %d failed: %s", p->sd, strerror(errno)); c->close(ctx, c); return status; } log_debug(LOG_NOTICE, "dyn: accepted c %d on p %d from '%s'", c->sd, p->sd, dn_unresolve_peer_desc(c->sd)); return DN_OK; }