Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3495593 authored by Chris Manton's avatar Chris Manton
Browse files

Fix run once thread cancel race condition

Bug: 277520864
Test: bluetooth_test_common64 --gtest_repeat=-1

Change-Id: Iebef72d0bc5155fd62da6653e11aefb2e7d832a6
parent b883e1f3
Loading
Loading
Loading
Loading
+26 −6
Original line number Original line Diff line number Diff line
@@ -16,11 +16,14 @@


#include "once_timer.h"
#include "once_timer.h"


#include <base/logging.h>

#include <memory>
#include <mutex>

#include "message_loop_thread.h"
#include "message_loop_thread.h"
#include "time_util.h"
#include "time_util.h"


#include <base/logging.h>

namespace bluetooth {
namespace bluetooth {


namespace common {
namespace common {
@@ -48,7 +51,12 @@ bool OnceTimer::Schedule(const base::WeakPtr<MessageLoopThread>& thread,
  task_ = std::move(task);
  task_ = std::move(task);
  task_wrapper_.Reset(
  task_wrapper_.Reset(
      base::BindOnce(&OnceTimer::RunTask, base::Unretained(this)));
      base::BindOnce(&OnceTimer::RunTask, base::Unretained(this)));
  {
    std::unique_lock<decltype(message_loop_thread_write_mutex_)> lock(
        message_loop_thread_write_mutex_);
    message_loop_thread_ = thread;
    message_loop_thread_ = thread;
  }

  delay_ = delay;
  delay_ = delay;
  uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us();
  uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us();
  if (!thread->DoInThreadDelayed(
  if (!thread->DoInThreadDelayed(
@@ -62,7 +70,11 @@ bool OnceTimer::Schedule(const base::WeakPtr<MessageLoopThread>& thread,
               << ": failed to post task to message loop for thread " << *thread
               << ": failed to post task to message loop for thread " << *thread
               << ", from " << from_here.ToString();
               << ", from " << from_here.ToString();
    task_wrapper_.Cancel();
    task_wrapper_.Cancel();
    {
      std::unique_lock<decltype(message_loop_thread_write_mutex_)> lock(
          message_loop_thread_write_mutex_);
      message_loop_thread_ = nullptr;
      message_loop_thread_ = nullptr;
    }
    delay_ = {};
    delay_ = {};
    return false;
    return false;
  }
  }
@@ -102,8 +114,12 @@ void OnceTimer::CancelHelper(std::promise<void> promise) {


// This runs on message loop thread
// This runs on message loop thread
void OnceTimer::CancelClosure(std::promise<void> promise) {
void OnceTimer::CancelClosure(std::promise<void> promise) {
  message_loop_thread_ = nullptr;
  task_wrapper_.Cancel();
  task_wrapper_.Cancel();
  {
    std::unique_lock<decltype(message_loop_thread_write_mutex_)> lock(
        message_loop_thread_write_mutex_);
    message_loop_thread_ = nullptr;
  }
  delay_ = base::TimeDelta();
  delay_ = base::TimeDelta();
  promise.set_value();
  promise.set_value();
}
}
@@ -127,8 +143,12 @@ void OnceTimer::RunTask() {


  task_wrapper_.Cancel();
  task_wrapper_.Cancel();
  std::move(task_).Run();
  std::move(task_).Run();
  {
    std::unique_lock<decltype(message_loop_thread_write_mutex_)> lock(
        message_loop_thread_write_mutex_);
    message_loop_thread_ = nullptr;
    message_loop_thread_ = nullptr;
  }
  }
}


}  // namespace common
}  // namespace common


+1 −0
Original line number Original line Diff line number Diff line
@@ -78,6 +78,7 @@ class OnceTimer final {
  bool IsScheduled() const;
  bool IsScheduled() const;


 private:
 private:
  mutable std::mutex message_loop_thread_write_mutex_;
  base::WeakPtr<MessageLoopThread> message_loop_thread_;
  base::WeakPtr<MessageLoopThread> message_loop_thread_;
  base::CancelableOnceClosure task_wrapper_;
  base::CancelableOnceClosure task_wrapper_;
  base::OnceClosure task_;
  base::OnceClosure task_;