one_shot_event.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_ONE_SHOT_EVENT_H_
  5. #define BASE_ONE_SHOT_EVENT_H_
  6. #include <vector>
  7. #include "base/base_export.h"
  8. #include "base/callback_forward.h"
  9. #include "base/check.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "base/threading/thread_checker.h"
  12. #include "base/threading/thread_task_runner_handle.h"
  13. namespace base {
  14. class Location;
  15. class SingleThreadTaskRunner;
  16. class TimeDelta;
  17. // This class represents an event that's expected to happen once. It
  18. // allows clients to guarantee that code is run after the OneShotEvent
  19. // is signaled. If the OneShotEvent is destroyed before it's
  20. // signaled, the closures are destroyed without being run.
  21. //
  22. // This class is similar to a WaitableEvent combined with several
  23. // WaitableEventWatchers, but using it is simpler.
  24. //
  25. // This class is not thread-safe, and must be used from a single thread.
  26. class BASE_EXPORT OneShotEvent {
  27. public:
  28. OneShotEvent();
  29. // Use the following constructor to create an already signaled event. This is
  30. // useful if you construct the event on a different thread from where it is
  31. // used, in which case it is not possible to call Signal() just after
  32. // construction.
  33. explicit OneShotEvent(bool signaled);
  34. ~OneShotEvent();
  35. // True if Signal has been called. This function is mostly for
  36. // migrating old code; usually calling Post() unconditionally will
  37. // result in more readable code.
  38. bool is_signaled() const {
  39. DCHECK(thread_checker_.CalledOnValidThread());
  40. return signaled_;
  41. }
  42. // Causes is_signaled() to return true and all tasks to be posted to their
  43. // corresponding task runners in the FIFO order. Note that tasks posted to
  44. // different SingleThreadTaskRunners may still execute in arbitrary order.
  45. // This method must only be called once.
  46. void Signal();
  47. // Scheduled |task| to be called on |runner| after is_signaled()
  48. // becomes true. If called with |delay|, then the task will happen
  49. // (roughly) |delay| after is_signaled(), *not* |delay| after the
  50. // post. Inside |task|, if this OneShotEvent is still alive,
  51. // CHECK(is_signaled()) will never fail (which implies that
  52. // OneShotEvent::Reset() doesn't exist).
  53. //
  54. // If |*this| is destroyed before being released, none of these
  55. // tasks will be executed.
  56. //
  57. // Tasks are posted in FIFO order, however, tasks posted to different
  58. // SingleThreadTaskRunners may still execute in an arbitrary order. Tasks will
  59. // never be called on the current thread before this function returns. Beware
  60. // that there's no simple way to wait for all tasks on a OneShotEvent to
  61. // complete, so it's almost never safe to use base::Unretained() when creating
  62. // one.
  63. void Post(const Location& from_here,
  64. OnceClosure task,
  65. scoped_refptr<SingleThreadTaskRunner> runner =
  66. ThreadTaskRunnerHandle::Get()) const;
  67. void PostDelayed(const Location& from_here,
  68. OnceClosure task,
  69. const TimeDelta& delay) const;
  70. private:
  71. struct TaskInfo;
  72. void PostImpl(const Location& from_here,
  73. OnceClosure task,
  74. scoped_refptr<SingleThreadTaskRunner> runner,
  75. const TimeDelta& delay) const;
  76. ThreadChecker thread_checker_;
  77. bool signaled_;
  78. // The task list is mutable because it's not part of the logical
  79. // state of the object. This lets us return const references to the
  80. // OneShotEvent to clients that just want to run tasks through it
  81. // without worrying that they'll signal the event.
  82. //
  83. // Optimization note: We could reduce the size of this class to a
  84. // single pointer by storing |signaled_| in the low bit of a
  85. // pointer, and storing the size and capacity of the array (if any)
  86. // on the far end of the pointer.
  87. mutable std::vector<TaskInfo> tasks_;
  88. };
  89. } // namespace base
  90. #endif // BASE_ONE_SHOT_EVENT_H_