diff options
author | Blake Oler <blake.oler@mongodb.com> | 2021-03-08 21:47:40 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-03-17 20:03:22 +0000 |
commit | d6fe0a7527ae541482fab025e2310a63f62583fc (patch) | |
tree | 7d1bbcf29321493571339207327dbb71c04801a1 /src/mongo | |
parent | 2a7d4e1159ee9484ffd1954b220957b1679b74c2 (diff) | |
download | mongo-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.cpp | 8 | ||||
-rw-r--r-- | src/mongo/util/fail_point.h | 8 | ||||
-rw-r--r-- | src/mongo/util/fail_point_test.cpp | 15 |
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); |