Skip to content

Commit 590f92b

Browse files
committed
CCBC-1651: ensure that purged packets get their memory released
mcreq_pipeline_timeout() function assumes that the packets have to be flushed to network buffers, but in case of network being configured to drop packets, the libcouchbase does not invoke flush routines as it still trying to connect sockets, so the requests would timeout without ever having chance to be written to network. In result, all buffers that associated with such requests will not be deallocated until the lcb_destroy() will be invoked on the instance. Change-Id: Iff19b5d84bd48a14a8bb8ae70e4ba311b21b79bf Reviewed-on: https://review.couchbase.org/c/libcouchbase/+/218172 Reviewed-by: Michael Reiche <michael.reiche@couchbase.com> Tested-by: Build Bot <build@couchbase.com>
1 parent d3013c8 commit 590f92b

1 file changed

Lines changed: 19 additions & 1 deletion

File tree

src/mc/mcreq.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,8 @@ void mcreq_sched_add(mc_PIPELINE *pipeline, mc_PACKET *pkt)
966966
mc_CMDQUEUE *cq = pipeline->parent;
967967
if (MCREQ_PKT_RDATA(pkt)->deadline == 0) {
968968
lcb_INSTANCE *instance = (lcb_INSTANCE *)pipeline->parent->cqdata;
969-
MCREQ_PKT_RDATA(pkt)->deadline = instance ? LCBT_SETTING(instance, operation_timeout) : LCB_DEFAULT_TIMEOUT;
969+
MCREQ_PKT_RDATA(pkt)->deadline =
970+
gethrtime() + LCB_US2NS(instance ? LCBT_SETTING(instance, operation_timeout) : LCB_DEFAULT_TIMEOUT);
970971
}
971972
lcb_assert(pipeline->index >= 0 && pipeline->index < (int)cq->_npipelines_ex);
972973
if (!cq->scheds[pipeline->index]) {
@@ -1038,6 +1039,7 @@ void mcreq_reset_timeouts(mc_PIPELINE *pl, lcb_U64 nstime)
10381039
SLLIST_ITERBASIC(&pl->requests, nn)
10391040
{
10401041
mc_PACKET *pkt = SLLIST_ITEM(nn, mc_PACKET, slnode);
1042+
lcb_assert(MCREQ_PKT_RDATA(pkt)->deadline >= MCREQ_PKT_RDATA(pkt)->start);
10411043
hrtime_t old_timeout = (MCREQ_PKT_RDATA(pkt)->deadline - MCREQ_PKT_RDATA(pkt)->start);
10421044
MCREQ_PKT_RDATA(pkt)->start = nstime;
10431045
MCREQ_PKT_RDATA(pkt)->deadline = nstime + old_timeout;
@@ -1056,6 +1058,22 @@ unsigned mcreq_pipeline_timeout(mc_PIPELINE *pl, lcb_STATUS err, mcreq_pktfail_f
10561058
if (now == 0 || rd->deadline <= now) {
10571059
sllist_iter_remove(&pl->requests, &iter);
10581060
failcb(pl, pkt, err, cbarg);
1061+
if ((pkt->flags & MCREQ_F_FLUSHED) == 0) {
1062+
/* the packet has not been flushed yet, remove it from sendq */
1063+
nb_SENDQ *q = &pl->nbmgr.sendq;
1064+
sllist_iterator i;
1065+
SLLIST_ITERFOR(&q->pdus, &i)
1066+
{
1067+
mc_PACKET *p = SLLIST_ITEM(i.cur, mc_PACKET, sl_flushq);
1068+
if (p == pkt) {
1069+
sllist_iter_remove(&q->pdus, &i);
1070+
break;
1071+
}
1072+
}
1073+
/* allow to release the packet */
1074+
pkt->flags |= MCREQ_F_FLUSHED;
1075+
}
1076+
10591077
mcreq_packet_handled(pl, pkt);
10601078
count++;
10611079
}

0 commit comments

Comments
 (0)