libzypp  17.35.14
timer.cc
Go to the documentation of this file.
1 #include "timer.h"
2 #include "private/base_p.h"
3 
4 #include "eventdispatcher.h"
5 
8 #include <glib.h>
9 
10 namespace zyppng {
11 
12 using namespace zypp;
13 
14 
16 {
18 public:
19  TimerPrivate(Timer &p);
20 
21  TimerPrivate(const TimerPrivate &) = delete;
22  TimerPrivate(TimerPrivate &&) = delete;
23  TimerPrivate &operator=(const TimerPrivate &) = delete;
24  TimerPrivate &operator=(TimerPrivate &&) = delete;
25 
26  ~TimerPrivate() override;
27 
28  uint64_t _beginMs = 0;
29  uint64_t _requestedTimeout = 0;
30  std::weak_ptr<EventDispatcher> _ev;
31  bool _isRunning = false;
32 
34 
35  bool _singleShot = false;
36 
37 };
38 
40 
42 {
43  auto ev = EventDispatcher::instance();
44  if ( !ev )
45  ZYPP_THROW( zypp::Exception( "Creating timers without a EventDispatcher instance is not supported" ) );
46  _ev = ev;
47 }
48 
50 {}
51 
52 std::shared_ptr<Timer> Timer::create()
53 {
54  return std::shared_ptr<Timer>( new Timer() );
55 }
56 
58 { stop(); }
59 
60 void Timer::setSingleShot(bool singleShot)
61 {
62  d_func()->_singleShot = singleShot;
63 }
64 
65 bool Timer::singleShot() const
66 {
67  return d_func()->_singleShot;
68 }
69 
70 uint64_t Timer::now()
71 {
72  return static_cast<uint64_t>( g_get_monotonic_time () / 1000 );
73 #if 0
74  timespec now{0 ,0};
75  if ( clock_gettime( CLOCK_MONOTONIC_RAW, &now ) ) {
76  WAR << "Unable to get current monotonic time, timers will not work" << std::endl;
77  return 1;
78  }
79  return ( uint(now.tv_sec) * 1000 ) + uint( now.tv_nsec * 1e-6 );
80 #endif
81 }
82 
83 uint64_t Timer::elapsedSince( const uint64_t start )
84 {
85  uint64_t nowMs = now();
86  return ( nowMs - start );
87 }
88 
89 uint64_t Timer::started() const
90 {
91  return d_func()->_beginMs;
92 }
93 
94 uint64_t Timer::interval() const
95 {
96  return d_func()->_requestedTimeout;
97 }
98 
99 uint64_t Timer::remaining() const
100 {
101  Z_D();
102 
103  uint64_t elapsed = this->elapsed();
104  if ( elapsed >= d->_requestedTimeout )
105  return 0;
106  return ( d->_requestedTimeout - elapsed );
107 }
108 
109 uint64_t Timer::elapsed() const
110 {
111  Z_D();
112  return elapsedSince( d->_beginMs );
113 }
114 
115 uint64_t Timer::expires() const
116 {
117  return d_func()->_beginMs + d_func()->_requestedTimeout;
118 }
119 
121 {
122  return d_func()->_expired;
123 }
124 
125 uint64_t Timer::expire()
126 {
127  Z_D();
128  //@FIXME, we should not rely on this, maybe a "deleteLater" feature
129  //in the MainLoop?
130  //make sure timer is not deleted during signal emission
131  auto lock = shared_from_this();
132 
133  auto exp = remaining();
134  if ( exp == 0 ) {
135  if ( d->_singleShot )
136  stop();
137  else
138  d->_beginMs = now();
139  d->_expired.emit( *this );
140  }
141  return exp;
142 }
143 
144 bool Timer::isRunning() const
145 {
146  return d_func()->_isRunning;
147 }
148 
150 {
151  start ( d_func()->_requestedTimeout );
152 }
153 
154 void Timer::start( uint64_t timeout )
155 {
156  Z_D();
157 
158  d->_requestedTimeout = timeout;
159  d->_beginMs = now();
160 
161  if ( !d->_isRunning ) {
162  auto ev = d->_ev.lock();
163  //if ev is null we are shutting down
164  if ( !ev )
165  return;
166  ev->registerTimer( *this );
167 
168  d->_isRunning = true;
169  }
170 
171 }
172 
174 {
175  Z_D();
176 
177  if ( !d->_isRunning )
178  return;
179 
180  auto ev = d->_ev.lock();
181 
182  //event loop might be shutting down
183  if ( ev )
184  ev->removeTimer( *this );
185 
186  d->_isRunning = false;
187 }
188 
189 Timer::Timer() : Base ( *new TimerPrivate( *this ) )
190 { }
191 
192 }
uint64_t interval() const
Definition: timer.cc:94
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:424
std::weak_ptr< EventDispatcher > _ev
Definition: timer.cc:30
~TimerPrivate() override
Definition: timer.cc:49
SignalProxy< void(Timer &t)> sigExpired()
This signal is always emitted when the timer expires.
Definition: timer.cc:120
#define Z_D()
Definition: zyppglobal.h:105
void stop()
Stops the timer if it is running. The.
Definition: timer.cc:173
uint64_t expires() const
Definition: timer.cc:115
void setSingleShot(bool singleShot=true)
Sets the timer to trigger only once, after it has expired once.
Definition: timer.cc:60
void start()
Definition: timer.cc:149
#define WAR
Definition: Logger.h:101
The Timer class provides repetitive and single-shot timers.
Definition: timer.h:44
static std::shared_ptr< EventDispatcher > instance()
uint64_t elapsed() const
Definition: timer.cc:109
~Timer() override
Definition: timer.cc:57
uint64_t remaining() const
Definition: timer.cc:99
static std::shared_ptr< Timer > create()
Creates a new Timer object, the timer is not started at this point.
Definition: timer.cc:52
uint64_t expire()
Advances the internal clock of the timer, if the timer expires the sigExpired signal is emitted...
Definition: timer.cc:125
Base class for Exception.
Definition: Exception.h:146
Signal< void(Timer &t)> _expired
Definition: timer.cc:33
static uint64_t now()
Definition: timer.cc:70
ZYPP_IMPL_PRIVATE(UnixSignalSource)
bool singleShot() const
Definition: timer.cc:65
bool isRunning() const
Definition: timer.cc:144
#define ZYPP_DECLARE_PUBLIC(Class)
Definition: zyppglobal.h:98
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
uint64_t started() const
Definition: timer.cc:89
static uint64_t elapsedSince(const uint64_t start)
Definition: timer.cc:83