summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorBlake Oler <blake.oler@mongodb.com>2021-03-08 21:47:40 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-17 20:03:22 +0000
commitd6fe0a7527ae541482fab025e2310a63f62583fc (patch)
tree7d1bbcf29321493571339207327dbb71c04801a1 /src/mongo
parent2a7d4e1159ee9484ffd1954b220957b1679b74c2 (diff)
downloadmongo-d6fe0a7527ae541482fab025e2310a63f62583fc.tar.gz
SERVER-54996 Change FailPoint::pauseWhileSetAndNotCanceled() to throw on cancelation
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/executor/task_executor.cpp8
-rw-r--r--src/mongo/util/fail_point.h8
-rw-r--r--src/mongo/util/fail_point_test.cpp15
3 files changed, 27 insertions, 4 deletions
diff --git a/src/mongo/executor/task_executor.cpp b/src/mongo/executor/task_executor.cpp
index 1f3fe80e6bc..89b136a3fee 100644
--- a/src/mongo/executor/task_executor.cpp
+++ b/src/mongo/executor/task_executor.cpp
@@ -95,8 +95,12 @@ ExecutorFuture<Response> wrapScheduleCallWithCancelTokenAndFuture(
// Fail point to make this method to wait until the token is canceled.
if (!token.isCanceled()) {
- pauseScheduleCallWithCancelTokenUntilCanceled.pauseWhileSetAndNotCanceled(
- Interruptible::notInterruptible(), token);
+ try {
+ pauseScheduleCallWithCancelTokenUntilCanceled.pauseWhileSetAndNotCanceled(
+ Interruptible::notInterruptible(), token);
+ } catch (ExceptionFor<ErrorCodes::Interrupted>&) {
+ // Swallow the interrupted exception that arrives from canceling a failpoint.
+ }
}
auto scheduleStatus = wrapCallbackHandleWithCancelToken(
diff --git a/src/mongo/util/fail_point.h b/src/mongo/util/fail_point.h
index 50b3b57ee08..657b4e1f107 100644
--- a/src/mongo/util/fail_point.h
+++ b/src/mongo/util/fail_point.h
@@ -39,6 +39,7 @@
#include "mongo/platform/atomic_word.h"
#include "mongo/platform/mutex.h"
#include "mongo/stdx/unordered_map.h"
+#include "mongo/util/assert_util.h"
#include "mongo/util/cancelation.h"
#include "mongo/util/duration.h"
#include "mongo/util/interruptible.h"
@@ -206,7 +207,9 @@ private:
void pauseWhileSetAndNotCanceled(Interruptible* interruptible,
const CancelationToken& token) {
auto alreadyCounted = AlreadyCounted{false};
- while (MONGO_unlikely(_shouldFail(alreadyCounted, nullptr)) && !token.isCanceled()) {
+ while (MONGO_unlikely(_shouldFail(alreadyCounted, nullptr))) {
+ uassert(
+ ErrorCodes::Interrupted, "Failpoint has been canceled", !token.isCanceled());
interruptible->sleepFor(_kWaitGranularity);
alreadyCounted = AlreadyCounted{true};
}
@@ -513,7 +516,8 @@ public:
/**
* Like `pauseWhileSet`, but will also unpause as soon as the cancellation token is canceled.
- * This method does not generate any cancellation related error by itself, it only waits.
+ * This method will throw if the token is canceled, to match the behavior when the
+ * Interruptible* is interrupted.
*/
void pauseWhileSetAndNotCanceled(Interruptible* interruptible, const CancelationToken& token) {
_impl()->pauseWhileSetAndNotCanceled(interruptible, token);
diff --git a/src/mongo/util/fail_point_test.cpp b/src/mongo/util/fail_point_test.cpp
index 5b4a9b639f0..4dafd26c6e8 100644
--- a/src/mongo/util/fail_point_test.cpp
+++ b/src/mongo/util/fail_point_test.cpp
@@ -483,6 +483,21 @@ TEST(FailPoint, PauseWhileSetInterruptibility) {
failPoint.setMode(FailPoint::off);
}
+TEST(FailPoint, PauseWhileSetCancelability) {
+ FailPoint failPoint("testFP");
+ failPoint.setMode(FailPoint::alwaysOn);
+
+ CancelationSource cs;
+ CancelationToken ct = cs.token();
+ cs.cancel();
+
+ ASSERT_THROWS_CODE(failPoint.pauseWhileSetAndNotCanceled(Interruptible::notInterruptible(), ct),
+ DBException,
+ ErrorCodes::Interrupted);
+
+ failPoint.setMode(FailPoint::off);
+}
+
TEST(FailPoint, WaitForFailPointTimeout) {
FailPoint failPoint("testFP");
failPoint.setMode(FailPoint::alwaysOn);