BUG/MINOR: sink: fix a race condition between the writer and the reader
This is the same issue as just fixed in b8e0fb97f
("BUG/MINOR: ring/cli:
fix a race condition between the writer and the reader") but this time
for sinks. They're also sucking the ring and present the same race at
high write loads.
This must be backported to 2.2 as well. See comments in the aforementioned
commit for backport hints if needed.
This commit is contained in:
parent
96417f392d
commit
53bfab080c
13
src/sink.c
13
src/sink.c
|
@ -306,7 +306,7 @@ static void sink_forward_io_handler(struct appctx *appctx)
|
|||
struct ring *ring = sink->ctx.ring;
|
||||
struct buffer *buf = &ring->buf;
|
||||
uint64_t msg_len;
|
||||
size_t len, cnt, ofs;
|
||||
size_t len, cnt, ofs, last_ofs;
|
||||
int ret = 0;
|
||||
|
||||
/* if stopping was requested, close immediately */
|
||||
|
@ -409,6 +409,7 @@ static void sink_forward_io_handler(struct appctx *appctx)
|
|||
HA_ATOMIC_INC(b_peek(buf, ofs));
|
||||
ofs += ring->ofs;
|
||||
sft->ofs = ofs;
|
||||
last_ofs = ring->ofs;
|
||||
}
|
||||
HA_RWLOCK_RDUNLOCK(LOGSRV_LOCK, &ring->lock);
|
||||
|
||||
|
@ -416,8 +417,16 @@ static void sink_forward_io_handler(struct appctx *appctx)
|
|||
/* let's be woken up once new data arrive */
|
||||
HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &ring->lock);
|
||||
LIST_APPEND(&ring->waiters, &appctx->wait_entry);
|
||||
ofs = ring->ofs;
|
||||
HA_RWLOCK_WRUNLOCK(LOGSRV_LOCK, &ring->lock);
|
||||
applet_have_no_more_data(appctx);
|
||||
if (ofs != last_ofs) {
|
||||
/* more data was added into the ring between the
|
||||
* unlock and the lock, and the writer might not
|
||||
* have seen us. We need to reschedule a read.
|
||||
*/
|
||||
applet_have_more_data(appctx);
|
||||
} else
|
||||
applet_have_no_more_data(appctx);
|
||||
}
|
||||
HA_SPIN_UNLOCK(SFT_LOCK, &sft->lock);
|
||||
|
||||
|
|
Loading…
Reference in New Issue