diff --git a/internal/platform/implementation/windows/scheduled_executor.cc b/internal/platform/implementation/windows/scheduled_executor.cc index ea004989..e420e96a 100644 --- a/internal/platform/implementation/windows/scheduled_executor.cc +++ b/internal/platform/implementation/windows/scheduled_executor.cc @@ -16,7 +16,6 @@ #include -#include #include #include @@ -25,6 +24,7 @@ #include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/implementation/cancelable.h" #include "internal/platform/logging.h" +#include "internal/platform/mutex_lock.h" #include "internal/platform/runnable.h" namespace nearby { @@ -40,6 +40,7 @@ ScheduledExecutor::ScheduledExecutor() // using std:shared_ptr<> instead of std::unique_ptr<>. std::shared_ptr ScheduledExecutor::Schedule( Runnable&& runnable, absl::Duration duration) { + MutexLock lock(&mutex_); if (NearbyFlags::GetInstance().GetBoolFlag( platform::config_package_nearby::nearby_platform_feature:: kEnableTaskScheduler)) { @@ -53,9 +54,14 @@ std::shared_ptr ScheduledExecutor::Schedule( } // Cleans completed tasks - (void)std::remove_if( - scheduled_tasks_.begin(), scheduled_tasks_.end(), - [](std::shared_ptr& task) { return task->IsDone(); }); + auto it = scheduled_tasks_.begin(); + while (it != scheduled_tasks_.end()) { + if ((*it)->IsDone()) { + it = scheduled_tasks_.erase(it); + } else { + ++it; + } + } std::shared_ptr task = std::make_shared(std::move(runnable), duration); @@ -67,6 +73,7 @@ std::shared_ptr ScheduledExecutor::Schedule( } void ScheduledExecutor::Execute(Runnable&& runnable) { + MutexLock lock(&mutex_); if (shut_down_) { NEARBY_LOGS(ERROR) << __func__ << ": Attempt to Execute on a shut down executor."; @@ -77,6 +84,7 @@ void ScheduledExecutor::Execute(Runnable&& runnable) { } void ScheduledExecutor::Shutdown() { + MutexLock lock(&mutex_); if (!shut_down_) { shut_down_ = true; for (auto& task : scheduled_tasks_) { diff --git a/internal/platform/implementation/windows/scheduled_executor.h b/internal/platform/implementation/windows/scheduled_executor.h index 8d87f2ea..65aed27f 100644 --- a/internal/platform/implementation/windows/scheduled_executor.h +++ b/internal/platform/implementation/windows/scheduled_executor.h @@ -22,12 +22,14 @@ #include #include +#include "absl/base/thread_annotations.h" #include "absl/synchronization/notification.h" #include "absl/time/time.h" #include "internal/platform/implementation/cancelable.h" #include "internal/platform/implementation/scheduled_executor.h" #include "internal/platform/implementation/windows/executor.h" #include "internal/platform/implementation/windows/task_scheduler.h" +#include "internal/platform/mutex.h" #include "internal/platform/runnable.h" namespace nearby { @@ -50,13 +52,14 @@ class ScheduledExecutor : public api::ScheduledExecutor { // Exclusive ownership model does not work for this case; // using std:shared_ptr<> instead if std::unique_ptr<>. std::shared_ptr Schedule(Runnable&& runnable, - absl::Duration duration) override; + absl::Duration duration) override + ABSL_LOCKS_EXCLUDED(mutex_); - // Executes the runnable task immedately. - void Execute(Runnable&& runnable) override; + // Executes the runnable task immediately. + void Execute(Runnable&& runnable) override ABSL_LOCKS_EXCLUDED(mutex_); // Shutdowns the executor, all scheduled task will be cancelled. - void Shutdown() override; + void Shutdown() override ABSL_LOCKS_EXCLUDED(mutex_); private: class ScheduledTask : public api::Cancelable { @@ -94,10 +97,13 @@ class ScheduledExecutor : public api::ScheduledExecutor { bool is_executed_ = false; }; - std::unique_ptr executor_ = nullptr; - std::vector> scheduled_tasks_; - std::atomic_bool shut_down_ = false; - TaskScheduler task_scheduler_; + Mutex mutex_; + std::unique_ptr executor_ ABSL_GUARDED_BY(mutex_) = + nullptr; + std::vector> scheduled_tasks_ + ABSL_GUARDED_BY(mutex_); + std::atomic_bool shut_down_ ABSL_GUARDED_BY(mutex_) = false; + TaskScheduler task_scheduler_ ABSL_GUARDED_BY(mutex_); }; } // namespace windows