rgw: Don't hold mutex over yield in LazyFIFO

If the FIFO doesn't exist, let clients race to create it, then stash
and use whoever wins.

Fixes: https://tracker.ceph.com/issues/63373
Signed-off-by: Adam Emerson <aemerson@redhat.com>
This commit is contained in:
Adam Emerson 2023-12-21 14:54:08 -05:00
parent 86bb77eb96
commit 8fa844383f

View File

@ -262,12 +262,24 @@ class LazyFIFO {
int lazy_init(const DoutPrefixProvider *dpp, optional_yield y) {
std::unique_lock l(m);
if (fifo) return 0;
auto r = rgw::cls::fifo::FIFO::create(dpp, ioctx, oid, &fifo, y);
if (r) {
fifo.reset();
if (fifo) {
return 0;
} else {
l.unlock();
// FIFO supports multiple clients by design, so it's safe to
// race to create them.
std::unique_ptr<rgw::cls::fifo::FIFO> fifo_tmp;
auto r = rgw::cls::fifo::FIFO::create(dpp, ioctx, oid, &fifo, y);
if (r) {
return r;
}
l.lock();
if (!fifo) {
// We won the race
fifo = std::move(fifo_tmp);
}
}
return r;
return 0;
}
public: