diff options
author | Jordi Olivares Provencio <jordi.olivares-provencio@mongodb.com> | 2022-04-19 08:19:57 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-19 13:17:34 +0000 |
commit | bd89da11e03f29f2d7beb37043a134e58a91f7b0 (patch) | |
tree | d1ddd353b0cbe1d3814b333dd116b20315221204 /src/mongo/util | |
parent | 496a3233aae099c2aa95f739e3c0b03c9cd8c504 (diff) | |
download | mongo-bd89da11e03f29f2d7beb37043a134e58a91f7b0.tar.gz |
SERVER-65542 Fix ticket resize
(cherry picked from commit 1cb9c79cdffc6dcf4a6b30045100483f8e121a33)
Diffstat (limited to 'src/mongo/util')
-rw-r--r-- | src/mongo/util/concurrency/ticket.h | 8 | ||||
-rw-r--r-- | src/mongo/util/concurrency/ticketholder.cpp | 17 | ||||
-rw-r--r-- | src/mongo/util/concurrency/ticketholder.h | 4 | ||||
-rw-r--r-- | src/mongo/util/concurrency/ticketholder_test.cpp | 29 |
4 files changed, 39 insertions, 19 deletions
diff --git a/src/mongo/util/concurrency/ticket.h b/src/mongo/util/concurrency/ticket.h index de4d7d78016..3f10db3e6a1 100644 --- a/src/mongo/util/concurrency/ticket.h +++ b/src/mongo/util/concurrency/ticket.h @@ -71,14 +71,8 @@ public: return _valid; } - Ticket() : _valid(false) {} - private: - static Ticket makeValid() { - Ticket ticket; - ticket._valid = true; - return ticket; - } + Ticket() : _valid(true) {} void release() { invariant(_valid); diff --git a/src/mongo/util/concurrency/ticketholder.cpp b/src/mongo/util/concurrency/ticketholder.cpp index 6c4ee52bf5f..aecf15065a6 100644 --- a/src/mongo/util/concurrency/ticketholder.cpp +++ b/src/mongo/util/concurrency/ticketholder.cpp @@ -91,7 +91,7 @@ boost::optional<Ticket> SemaphoreTicketHolder::tryAcquire(AdmissionContext* admC if (errno != EINTR) failWithErrno(errno); } - return boost::make_optional(Ticket::makeValid()); + return Ticket{}; } Ticket SemaphoreTicketHolder::waitForTicket(OperationContext* opCtx, @@ -106,11 +106,10 @@ boost::optional<Ticket> SemaphoreTicketHolder::waitForTicketUntil(OperationConte AdmissionContext* admCtx, Date_t until, WaitMode waitMode) { - invariant(opCtx); // Attempt to get a ticket without waiting in order to avoid expensive time calculations. if (sem_trywait(&_sem) == 0) { - return boost::make_optional(Ticket::makeValid()); + return Ticket{}; } const Milliseconds intervalMs(500); @@ -140,7 +139,7 @@ boost::optional<Ticket> SemaphoreTicketHolder::waitForTicketUntil(OperationConte if (waitMode == WaitMode::kInterruptible) opCtx->checkForInterrupt(); } - return boost::make_optional(Ticket::makeValid()); + return Ticket{}; } void SemaphoreTicketHolder::release(AdmissionContext* admCtx, Ticket&& ticket) { @@ -169,6 +168,7 @@ Status SemaphoreTicketHolder::resize(int newSize) { while (_outof.load() > newSize) { auto ticket = waitForTicket(nullptr, &admCtx, WaitMode::kUninterruptible); + ticket.release(); _outof.subtractAndFetch(1); } @@ -380,7 +380,7 @@ boost::optional<Ticket> FifoTicketHolder::tryAcquire(AdmissionContext* admCtx) { } admCtx->start(_serviceContext->getTickSource()); _totalStartedProcessing.fetchAndAddRelaxed(1); - return boost::make_optional(Ticket::makeValid()); + return Ticket{}; } Ticket FifoTicketHolder::waitForTicket(OperationContext* opCtx, @@ -436,7 +436,7 @@ boost::optional<Ticket> FifoTicketHolder::waitForTicketUntil(OperationContext* o if (remaining >= 0) { _enqueuedElements.subtractAndFetch(1); startProcessing(); - return boost::make_optional(Ticket::makeValid()); + return Ticket{}; } _ticketsAvailable.addAndFetch(1); // We copy-construct the shared_ptr here as the waiting element needs to be alive in both @@ -458,7 +458,7 @@ boost::optional<Ticket> FifoTicketHolder::waitForTicketUntil(OperationContext* o // To cover the edge case of getting a ticket assigned before cancelling the ticket // request. As we have been granted a ticket we must release it. startProcessing(); - release(admCtx, Ticket()); + release(admCtx, Ticket{}); } }); @@ -485,7 +485,7 @@ boost::optional<Ticket> FifoTicketHolder::waitForTicketUntil(OperationContext* o if (assigned) { cancelWait.dismiss(); startProcessing(); - return boost::make_optional(Ticket::makeValid()); + return Ticket{}; } else { return boost::none; } @@ -508,6 +508,7 @@ Status FifoTicketHolder::resize(int newSize) { while (_capacity.load() > newSize) { Ticket ticket = waitForTicket(nullptr, &admCtx, WaitMode::kUninterruptible); + ticket.release(); _capacity.subtractAndFetch(1); } diff --git a/src/mongo/util/concurrency/ticketholder.h b/src/mongo/util/concurrency/ticketholder.h index d24530ffac6..a03518f908b 100644 --- a/src/mongo/util/concurrency/ticketholder.h +++ b/src/mongo/util/concurrency/ticketholder.h @@ -227,10 +227,6 @@ class TicketHolderReleaser { TicketHolderReleaser& operator=(const TicketHolderReleaser&) = delete; public: - TicketHolderReleaser() { - _holder = nullptr; - } - explicit TicketHolderReleaser(Ticket&& ticket, AdmissionContext* admCtx, TicketHolder* holder) : _holder(holder), _ticket(std::move(ticket)), _admCtx(admCtx) {} diff --git a/src/mongo/util/concurrency/ticketholder_test.cpp b/src/mongo/util/concurrency/ticketholder_test.cpp index d60a39d02dc..5f0fed6769b 100644 --- a/src/mongo/util/concurrency/ticketholder_test.cpp +++ b/src/mongo/util/concurrency/ticketholder_test.cpp @@ -100,6 +100,35 @@ void basicTimeout(OperationContext* opCtx) { ASSERT_FALSE(holder->waitForTicketUntil(opCtx, &admCtx, Date_t::now() + Milliseconds(2), mode)); holder->release(&admCtx, std::move(*ticket)); ASSERT_EQ(holder->used(), 0); + + // + // Test resize + // + ASSERT(holder->resize(6).isOK()); + ticket = holder->waitForTicket(opCtx, &admCtx, mode); + ASSERT(ticket); + ASSERT_EQ(holder->used(), 1); + ASSERT_EQ(holder->outof(), 6); + + std::array<boost::optional<Ticket>, 5> tickets; + for (int i = 0; i < 5; ++i) { + tickets[i] = holder->waitForTicket(opCtx, &admCtx, mode); + ASSERT_EQ(holder->used(), 2 + i); + ASSERT_EQ(holder->outof(), 6); + } + + ASSERT_FALSE(holder->waitForTicketUntil(opCtx, &admCtx, Date_t::now() + Milliseconds(1), mode)); + + holder->release(&admCtx, std::move(*ticket)); + + ASSERT(holder->resize(5).isOK()); + ASSERT_EQ(holder->used(), 5); + ASSERT_EQ(holder->outof(), 5); + ASSERT_FALSE(holder->waitForTicketUntil(opCtx, &admCtx, Date_t::now() + Milliseconds(1), mode)); + + for (int i = 0; i < 5; ++i) { + holder->release(&admCtx, std::move(*tickets[i])); + } } TEST_F(TicketHolderTest, BasicTimeoutFifo) { |