diff --git a/sandboxed_api/sandbox2/util/deadline_manager.cc b/sandboxed_api/sandbox2/util/deadline_manager.cc index 51d0d6ef..661238c3 100644 --- a/sandboxed_api/sandbox2/util/deadline_manager.cc +++ b/sandboxed_api/sandbox2/util/deadline_manager.cc @@ -100,6 +100,8 @@ void DeadlineManager::AdjustDeadline(DeadlineRegistration& registration, absl::Time deadline) { absl::MutexLock lock(&queue_mutex_); queue_.erase(registration.data_.get()); + absl::MutexLock data_lock(®istration.data_->mutex); + registration.data_->expired = false; registration.data_->deadline = RoundUpTo(deadline, kResolution); if (deadline != absl::InfiniteFuture()) { queue_.insert(registration.data_.get()); diff --git a/sandboxed_api/sandbox2/util/deadline_manager.h b/sandboxed_api/sandbox2/util/deadline_manager.h index 5fe4fd73..727282f2 100644 --- a/sandboxed_api/sandbox2/util/deadline_manager.h +++ b/sandboxed_api/sandbox2/util/deadline_manager.h @@ -71,7 +71,7 @@ class DeadlineRegistration { struct Data { absl::Mutex mutex; - // Changed only under DeadlineManager::queue_mutex_. + // Changed only under both DeadlineManager::queue_mutex_ and Data::mutex. absl::Time deadline = absl::InfiniteFuture(); pid_t ABSL_GUARDED_BY(mutex) tid = -1; bool ABSL_GUARDED_BY(mutex) in_blocking_fn = false; diff --git a/sandboxed_api/sandbox2/util/deadline_manager_test.cc b/sandboxed_api/sandbox2/util/deadline_manager_test.cc index 253d12ec..59bee9b5 100644 --- a/sandboxed_api/sandbox2/util/deadline_manager_test.cc +++ b/sandboxed_api/sandbox2/util/deadline_manager_test.cc @@ -112,5 +112,20 @@ TEST(DeadlineManagerTest, DeadlineReset) { EXPECT_GE(elapsed, absl::Milliseconds(200)); } +TEST(DeadlineManagerTest, CanBeReusedAfterExpiration) { + DeadlineManager manager("test"); + DeadlineRegistration registration(manager); + for (int i = 0; i < 3; ++i) { + absl::Time start_time = absl::Now(); + struct timespec ts = absl::ToTimespec(absl::Seconds(1)); + registration.SetDeadline(start_time + absl::Milliseconds(100)); + registration.ExecuteBlockingSyscall( + [&] { ASSERT_EQ(nanosleep(&ts, nullptr), -1); }); + absl::Duration elapsed = absl::Now() - start_time; + EXPECT_GE(elapsed, absl::Milliseconds(100)); + EXPECT_LE(elapsed, absl::Milliseconds(200)); + } +} + } // namespace } // namespace sandbox2