static void proxy_close(struct context *ctx, struct conn *conn) { rstatus_t status; ASSERT(conn->type == CONN_PROXY); if (conn->sd < 0) { conn_unref(conn); conn_put(conn); return; } ASSERT(conn->rmsg == NULL); ASSERT(conn->smsg == NULL); ASSERT(TAILQ_EMPTY(&conn->imsg_q)); ASSERT(TAILQ_EMPTY(&conn->omsg_q)); conn_unref(conn); status = close(conn->sd); if (status < 0) { log_error("close p %d failed, ignored: %s", conn->sd, strerror(errno)); } conn->sd = -1; conn_put(conn); }
void server_close(struct context *ctx, struct conn *conn) { rstatus_t status; struct msg *msg, *nmsg; /* current and next message */ ASSERT(conn->type == CONN_SERVER); server_close_stats(ctx, conn->owner, conn->err, conn->eof, conn->connected); if (conn->sd < 0) { server_failure(ctx, conn->owner); conn_unref(conn); conn_put(conn); return; } for (msg = TAILQ_FIRST(&conn->omsg_q); msg != NULL; msg = nmsg) { nmsg = TAILQ_NEXT(msg, s_tqe); /* dequeue the message (request) from server outq */ conn_dequeue_outq(ctx, conn, msg); server_ack_err(ctx, conn, msg); } ASSERT(TAILQ_EMPTY(&conn->omsg_q)); for (msg = TAILQ_FIRST(&conn->imsg_q); msg != NULL; msg = nmsg) { nmsg = TAILQ_NEXT(msg, s_tqe); /* dequeue the message (request) from server inq */ conn_dequeue_inq(ctx, conn, msg); // We should also remove the msg from the timeout rbtree. msg_tmo_delete(msg); server_ack_err(ctx, conn, msg); stats_server_incr(ctx, conn->owner, server_dropped_requests); } ASSERT(TAILQ_EMPTY(&conn->imsg_q)); msg = conn->rmsg; if (msg != NULL) { conn->rmsg = NULL; ASSERT(!msg->request); ASSERT(msg->peer == NULL); rsp_put(msg); log_debug(LOG_INFO, "close s %d discarding rsp %"PRIu64" len %"PRIu32" " "in error", conn->sd, msg->id, msg->mlen); } ASSERT(conn->smsg == NULL); server_failure(ctx, conn->owner); conn_unref(conn); status = close(conn->sd); if (status < 0) { log_error("close s %d failed, ignored: %s", conn->sd, strerror(errno)); } conn->sd = -1; conn_put(conn); }
static void dnode_client_close(struct context *ctx, struct conn *conn) { rstatus_t status; struct msg *msg, *nmsg; /* current and next message */ ASSERT(conn->type == CONN_DNODE_PEER_CLIENT); dnode_client_close_stats(ctx, conn->owner, conn->err, conn->eof); if (conn->sd < 0) { conn_unref(conn); conn_put(conn); return; } msg = conn->rmsg; if (msg != NULL) { conn->rmsg = NULL; ASSERT(msg->peer == NULL); ASSERT(msg->request && !msg->done); if (log_loggable(LOG_INFO)) { log_debug(LOG_INFO, "dyn: close c %d discarding pending req %"PRIu64" len " "%"PRIu32" type %d", conn->sd, msg->id, msg->mlen, msg->type); } dictDelete(conn->outstanding_msgs_dict, &msg->id); req_put(msg); } ASSERT(conn->smsg == NULL); ASSERT(TAILQ_EMPTY(&conn->imsg_q)); for (msg = TAILQ_FIRST(&conn->omsg_q); msg != NULL; msg = nmsg) { nmsg = TAILQ_NEXT(msg, c_tqe); /* dequeue the message (request) from client outq */ conn_dequeue_outq(ctx, conn, msg); if (msg->done) { if (log_loggable(LOG_INFO)) { log_debug(LOG_INFO, "dyn: close c %d discarding %s req %"PRIu64" len " "%"PRIu32" type %d", conn->sd, msg->error ? "error": "completed", msg->id, msg->mlen, msg->type); } dictDelete(conn->outstanding_msgs_dict, &msg->id); req_put(msg); } else { msg->swallow = 1; ASSERT(msg->request); ASSERT(msg->peer == NULL); if (log_loggable(LOG_INFO)) { log_debug(LOG_INFO, "dyn: close c %d schedule swallow of req %"PRIu64" " "len %"PRIu32" type %d", conn->sd, msg->id, msg->mlen, msg->type); } } } ASSERT(TAILQ_EMPTY(&conn->omsg_q)); conn_unref(conn); status = close(conn->sd); if (status < 0) { log_error("dyn: close c %d failed, ignored: %s", conn->sd, strerror(errno)); } conn->sd = -1; conn_put(conn); }