/** * Purge all entries from a queue. */ int rd_kafka_q_purge0 (rd_kafka_q_t *rkq, int do_lock) { rd_kafka_op_t *rko, *next; TAILQ_HEAD(, rd_kafka_op_s) tmpq = TAILQ_HEAD_INITIALIZER(tmpq); int cnt = 0; if (do_lock) mtx_lock(&rkq->rkq_lock); if (rkq->rkq_fwdq) { cnt = rd_kafka_q_purge(rkq->rkq_fwdq); if (do_lock) mtx_unlock(&rkq->rkq_lock); return cnt; } /* Move ops queue to tmpq to avoid lock-order issue * by locks taken from rd_kafka_op_destroy(). */ TAILQ_MOVE(&tmpq, &rkq->rkq_q, rko_link); /* Zero out queue */ rd_kafka_q_reset(rkq); if (do_lock) mtx_unlock(&rkq->rkq_lock); /* Destroy the ops */ next = TAILQ_FIRST(&tmpq); while ((rko = next)) { next = TAILQ_NEXT(next, rko_link); rd_kafka_op_destroy(rko); cnt++; } return cnt; }
/** * Initialize a queue. */ void rd_kafka_q_init (rd_kafka_q_t *rkq, rd_kafka_t *rk) { rd_kafka_q_reset(rkq); rkq->rkq_fwdq = NULL; rkq->rkq_refcnt = 1; rkq->rkq_flags = RD_KAFKA_Q_F_READY; rkq->rkq_rk = rk; mtx_init(&rkq->rkq_lock, mtx_plain); cnd_init(&rkq->rkq_cond); }
/** * Move 'cnt' entries from 'srcq' to 'dstq'. * If 'cnt' == -1 all entries will be moved. * Returns the number of entries moved. */ int rd_kafka_q_move_cnt (rd_kafka_q_t *dstq, rd_kafka_q_t *srcq, int cnt, int do_locks) { rd_kafka_op_t *rko; int mcnt = 0; if (do_locks) { mtx_lock(&srcq->rkq_lock); mtx_lock(&dstq->rkq_lock); } if (!dstq->rkq_fwdq && !srcq->rkq_fwdq) { if (cnt > 0 && dstq->rkq_qlen == 0) rd_kafka_q_io_event(dstq); /* Optimization, if 'cnt' is equal/larger than all * items of 'srcq' we can move the entire queue. */ if (cnt == -1 || cnt >= (int)srcq->rkq_qlen) { rd_dassert(TAILQ_EMPTY(&srcq->rkq_q) || srcq->rkq_qlen > 0); TAILQ_CONCAT(&dstq->rkq_q, &srcq->rkq_q, rko_link); mcnt = srcq->rkq_qlen; dstq->rkq_qlen += srcq->rkq_qlen; dstq->rkq_qsize += srcq->rkq_qsize; rd_kafka_q_reset(srcq); } else { while (mcnt < cnt && (rko = TAILQ_FIRST(&srcq->rkq_q))) { TAILQ_REMOVE(&srcq->rkq_q, rko, rko_link); TAILQ_INSERT_TAIL(&dstq->rkq_q, rko, rko_link); srcq->rkq_qlen--; dstq->rkq_qlen++; srcq->rkq_qsize -= rko->rko_len; dstq->rkq_qsize += rko->rko_len; mcnt++; } } } else mcnt = rd_kafka_q_move_cnt(dstq->rkq_fwdq ? dstq->rkq_fwdq:dstq, srcq->rkq_fwdq ? srcq->rkq_fwdq:srcq, cnt, do_locks); if (do_locks) { mtx_unlock(&dstq->rkq_lock); mtx_unlock(&srcq->rkq_lock); } return mcnt; }