Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/threads/TimerThread.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef TimerThread_h___
8
#define TimerThread_h___
9
10
#include "nsIObserver.h"
11
#include "nsIRunnable.h"
12
#include "nsIThread.h"
13
14
#include "nsTimerImpl.h"
15
#include "nsThreadUtils.h"
16
17
#include "nsTArray.h"
18
19
#include "mozilla/Atomics.h"
20
#include "mozilla/Attributes.h"
21
#include "mozilla/Monitor.h"
22
#include "mozilla/UniquePtr.h"
23
24
#include <algorithm>
25
26
namespace mozilla {
27
class TimeStamp;
28
} // namespace mozilla
29
30
class TimerThread final
31
  : public nsIRunnable
32
  , public nsIObserver
33
{
34
public:
35
  typedef mozilla::Monitor Monitor;
36
  typedef mozilla::TimeStamp TimeStamp;
37
  typedef mozilla::TimeDuration TimeDuration;
38
39
  TimerThread();
40
  nsresult InitLocks();
41
42
  NS_DECL_THREADSAFE_ISUPPORTS
43
  NS_DECL_NSIRUNNABLE
44
  NS_DECL_NSIOBSERVER
45
46
  nsresult Shutdown();
47
48
  nsresult AddTimer(nsTimerImpl* aTimer);
49
  nsresult RemoveTimer(nsTimerImpl* aTimer);
50
  TimeStamp FindNextFireTimeForCurrentThread(TimeStamp aDefault, uint32_t aSearchBound);
51
52
  void DoBeforeSleep();
53
  void DoAfterSleep();
54
55
  bool IsOnTimerThread() const
56
0
  {
57
0
    return mThread->SerialEventTarget()->IsOnCurrentThread();
58
0
  }
59
60
  uint32_t
61
  AllowedEarlyFiringMicroseconds() const;
62
63
private:
64
  ~TimerThread();
65
66
  bool    mInitialized;
67
68
  // These internal helper methods must be called while mMonitor is held.
69
  // AddTimerInternal returns false if the insertion failed.
70
  bool    AddTimerInternal(nsTimerImpl* aTimer);
71
  bool    RemoveTimerInternal(nsTimerImpl* aTimer);
72
  void    RemoveLeadingCanceledTimersInternal();
73
  void    RemoveFirstTimerInternal();
74
  nsresult Init();
75
76
  already_AddRefed<nsTimerImpl> PostTimerEvent(already_AddRefed<nsTimerImpl> aTimerRef);
77
78
  nsCOMPtr<nsIThread> mThread;
79
  Monitor mMonitor;
80
81
  bool mShutdown;
82
  bool mWaiting;
83
  bool mNotified;
84
  bool mSleeping;
85
86
  class Entry final : public nsTimerImplHolder
87
  {
88
    const TimeStamp mTimeout;
89
90
  public:
91
    Entry(const TimeStamp& aMinTimeout, const TimeStamp& aTimeout,
92
          nsTimerImpl* aTimerImpl)
93
      : nsTimerImplHolder(aTimerImpl)
94
      , mTimeout(std::max(aMinTimeout, aTimeout))
95
90
    {
96
90
    }
97
98
    nsTimerImpl*
99
    Value() const
100
631
    {
101
631
      return mTimerImpl;
102
631
    }
103
104
    already_AddRefed<nsTimerImpl>
105
    Take()
106
86
    {
107
86
      if (mTimerImpl) {
108
86
        mTimerImpl->SetHolder(nullptr);
109
86
      }
110
86
      return mTimerImpl.forget();
111
86
    }
112
113
    static bool
114
    UniquePtrLessThan(mozilla::UniquePtr<Entry>& aLeft,
115
                      mozilla::UniquePtr<Entry>& aRight)
116
11
    {
117
11
      // This is reversed because std::push_heap() sorts the "largest" to
118
11
      // the front of the heap.  We want that to be the earliest timer.
119
11
      return aRight->mTimeout < aLeft->mTimeout;
120
11
    }
121
122
    TimeStamp Timeout() const
123
0
    {
124
0
      return mTimeout;
125
0
    }
126
  };
127
128
  nsTArray<mozilla::UniquePtr<Entry>> mTimers;
129
  uint32_t mAllowedEarlyFiringMicroseconds;
130
};
131
132
#endif /* TimerThread_h___ */