| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2014 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 | 
|  | 5 #ifndef COMPONENTS_TIMER_RTC_ALARM_H_ | 
|  | 6 #define COMPONENTS_TIMER_RTC_ALARM_H_ | 
|  | 7 | 
|  | 8 #include "base/macros.h" | 
|  | 9 #include "base/memory/ref_counted.h" | 
|  | 10 #include "base/memory/scoped_ptr.h" | 
|  | 11 #include "base/memory/weak_ptr.h" | 
|  | 12 #include "base/message_loop/message_loop.h" | 
|  | 13 #include "base/time/time.h" | 
|  | 14 #include "components/timers/alarm_timer.h" | 
|  | 15 | 
|  | 16 namespace base { | 
|  | 17 class MessageLoopProxy; | 
|  | 18 } | 
|  | 19 | 
|  | 20 namespace timers { | 
|  | 21 // This class manages a Real Time Clock (RTC) alarm, a feature that is available | 
|  | 22 // from linux version 3.11 onwards.  It creates a file descriptor for the RTC | 
|  | 23 // alarm timer and then watches that file descriptor to see when it can be read | 
|  | 24 // without blocking, indicating that the timer has fired. | 
|  | 25 // | 
|  | 26 // A major problem for this class is that watching file descriptors is only | 
|  | 27 // available on a MessageLoopForIO but there is no guarantee the timer is going | 
|  | 28 // to be created on one.  To get around this, the timer has a dedicated thread | 
|  | 29 // with a MessageLoopForIO that posts tasks back to the thread that started the | 
|  | 30 // timer. | 
|  | 31 // | 
|  | 32 // This class is designed to work together with the AlarmTimer class and is | 
|  | 33 // tested through the AlarmTimer unit tests.  DO NOT TRY TO USE THIS CLASS | 
|  | 34 // DIRECTLY.  Or use it anyway, I'm a comment not a cop. | 
|  | 35 class RtcAlarm : public AlarmTimer::Delegate, | 
|  | 36                  public base::MessageLoopForIO::Watcher { | 
|  | 37  public: | 
|  | 38   RtcAlarm(); | 
|  | 39 | 
|  | 40   // AlarmTimer::Delegate overrides. | 
|  | 41   bool Init(base::WeakPtr<AlarmTimer> timer) override; | 
|  | 42   void Stop() override; | 
|  | 43   void Reset(base::TimeDelta delay) override; | 
|  | 44 | 
|  | 45   // base::MessageLoopForIO::Watcher overrides. | 
|  | 46   void OnFileCanReadWithoutBlocking(int fd) override; | 
|  | 47   void OnFileCanWriteWithoutBlocking(int fd) override; | 
|  | 48 | 
|  | 49  protected: | 
|  | 50   // Needs to be protected because AlarmTimer::Delegate is a refcounted class. | 
|  | 51   virtual ~RtcAlarm(); | 
|  | 52 | 
|  | 53  private: | 
|  | 54   // Actually performs the system calls to set up the timer.  This must be | 
|  | 55   // called on a MessageLoopForIO. | 
|  | 56   void ResetImpl(base::TimeDelta delay, int event_id); | 
|  | 57 | 
|  | 58   // Callback that is run when the timer fires.  Must be run on | 
|  | 59   // |origin_message_loop_|. | 
|  | 60   void OnTimerFired(int event_id); | 
|  | 61 | 
|  | 62   // File descriptor associated with the alarm timer. | 
|  | 63   int alarm_fd_; | 
|  | 64 | 
|  | 65   // Message loop which initially started the timer. | 
|  | 66   scoped_refptr<base::MessageLoopProxy> origin_message_loop_; | 
|  | 67 | 
|  | 68   // The parent timer that should be informed when the timer fires.  We may end | 
|  | 69   // up outliving the parent so we need to ensure the reference is valid before | 
|  | 70   // we try to call it. | 
|  | 71   base::WeakPtr<AlarmTimer> parent_; | 
|  | 72 | 
|  | 73   // Manages watching file descriptors. | 
|  | 74   scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> fd_watcher_; | 
|  | 75 | 
|  | 76   // These two variables are used for coordinating between the thread that | 
|  | 77   // started the timer and the IO thread being used to watch the timer file | 
|  | 78   // descriptor.  When Reset() is called, the original thread increments | 
|  | 79   // |origin_event_id_| and binds its value to ResetImpl(), which gets posted to | 
|  | 80   // the IO thread.  When the IO thread runs, it saves this value in | 
|  | 81   // |io_event_id_|.  Later, when the timer fires, the IO thread binds the value | 
|  | 82   // of |io_event_id_| to OnTimerFired() and posts it to the original thread. | 
|  | 83   // When the original thread runs OnTimerFired(), it calls | 
|  | 84   // parent_->OnTimerFired() only if |origin_event_id_| matches the event id | 
|  | 85   // that was passed in to it.  This is used to get around a race condition | 
|  | 86   // where the user resets the timer on the original thread, while the event is | 
|  | 87   // being fired on the IO thread at the same time. | 
|  | 88   int origin_event_id_; | 
|  | 89   int io_event_id_; | 
|  | 90 | 
|  | 91   DISALLOW_COPY_AND_ASSIGN(RtcAlarm); | 
|  | 92 }; | 
|  | 93 | 
|  | 94 }  // namespace timers | 
|  | 95 #endif  // COMPONENTS_TIMER_RTC_ALARM_H_ | 
| OLD | NEW | 
|---|