summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
authorJordi Olivares Provencio <jordi.olivares-provencio@mongodb.com>2022-04-19 08:19:57 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-19 13:17:34 +0000
commitbd89da11e03f29f2d7beb37043a134e58a91f7b0 (patch)
treed1ddd353b0cbe1d3814b333dd116b20315221204 /src/mongo/util
parent496a3233aae099c2aa95f739e3c0b03c9cd8c504 (diff)
downloadmongo-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.h8
-rw-r--r--src/mongo/util/concurrency/ticketholder.cpp17
-rw-r--r--src/mongo/util/concurrency/ticketholder.h4
-rw-r--r--src/mongo/util/concurrency/ticketholder_test.cpp29
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) {