From: Peter Dillinger Date: Thu, 22 Jul 2021 00:36:48 +0000 (-0700) Subject: Remove TaskLimiterToken::ReleaseOnce for fix (#8567) X-Git-Tag: v6.24.2~92 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=84eef260de9c0dc0c7ace8e6f605a2b3efd71038;p=rocksdb.git Remove TaskLimiterToken::ReleaseOnce for fix (#8567) Summary: Rare TSAN and valgrind failures are caused by unnecessary reading of a field on the TaskLimiterToken::limiter_ for an assertion after the token has been released and the limiter destroyed. To simplify we can simply destroy the token before triggering DB shutdown (potentially destroying the limiter). This makes the ReleaseOnce logic unnecessary. Pull Request resolved: https://github.com/facebook/rocksdb/pull/8567 Test Plan: watch for more failures in CI Reviewed By: ajkr Differential Revision: D29811795 Pulled By: pdillinger fbshipit-source-id: 135549ebb98fe4f176d1542ed85d5bd6350a40b3 --- diff --git a/db/db_impl/db_impl_compaction_flush.cc b/db/db_impl/db_impl_compaction_flush.cc index 2b771e360..515bd7422 100644 --- a/db/db_impl/db_impl_compaction_flush.cc +++ b/db/db_impl/db_impl_compaction_flush.cc @@ -2785,9 +2785,11 @@ void DBImpl::BackgroundCallCompaction(PrepickedCompaction* prepicked_compaction, if (prepicked_compaction != nullptr && prepicked_compaction->task_token != nullptr) { - // Releasing task tokens affects the DB state, so must be done before we - // potentially signal the DB close process to proceed below. - prepicked_compaction->task_token->ReleaseOnce(); + // Releasing task tokens affects (and asserts on) the DB state, so + // must be done before we potentially signal the DB close process to + // proceed below. + prepicked_compaction->task_token.reset(); + ; } if (made_progress || diff --git a/util/concurrent_task_limiter_impl.cc b/util/concurrent_task_limiter_impl.cc index efa01a17f..2342677d8 100644 --- a/util/concurrent_task_limiter_impl.cc +++ b/util/concurrent_task_limiter_impl.cc @@ -59,14 +59,9 @@ ConcurrentTaskLimiter* NewConcurrentTaskLimiter( return new ConcurrentTaskLimiterImpl(name, limit); } -void TaskLimiterToken::ReleaseOnce() { - if (!released_) { - --limiter_->outstanding_tasks_; - released_ = true; - } +TaskLimiterToken::~TaskLimiterToken() { + --limiter_->outstanding_tasks_; assert(limiter_->outstanding_tasks_ >= 0); } -TaskLimiterToken::~TaskLimiterToken() { ReleaseOnce(); } - } // namespace ROCKSDB_NAMESPACE diff --git a/util/concurrent_task_limiter_impl.h b/util/concurrent_task_limiter_impl.h index 0e6cf1466..d8c1e03cb 100644 --- a/util/concurrent_task_limiter_impl.h +++ b/util/concurrent_task_limiter_impl.h @@ -53,16 +53,11 @@ class ConcurrentTaskLimiterImpl : public ConcurrentTaskLimiter { class TaskLimiterToken { public: explicit TaskLimiterToken(ConcurrentTaskLimiterImpl* limiter) - : limiter_(limiter), released_(false) {} + : limiter_(limiter) {} ~TaskLimiterToken(); - // Releases the token from the `ConcurrentTaskLimiterImpl` if not already - // released. - // Not thread-safe. - void ReleaseOnce(); private: ConcurrentTaskLimiterImpl* limiter_; - bool released_; // no copying allowed TaskLimiterToken(const TaskLimiterToken&) = delete;