Fawkes API  Fawkes Development Version
timer_thread.cpp
1 
2 /***************************************************************************
3  * timer_thread.cpp - timer thread
4  *
5  * Created: Mon Aug 13 16:21:32 2018
6  * Copyright 2006-2018 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "timer_thread.h"
23 
24 #include <core/threading/mutex.h>
25 #include <core/threading/mutex_locker.h>
26 #include <core/threading/wait_condition.h>
27 
28 using namespace fawkes;
29 
30 /** @class PlexilTimerThread "timer_thread.h"
31  * Timer support class.
32  * @author Tim Niemueller
33  */
34 
35 /** Constructor. */
36 PlexilTimerThread::PlexilTimerThread() : Thread("PlexilTimerThread", Thread::OPMODE_WAITFORWAKEUP)
37 {
38  mutex_ = new Mutex();
39  waitcond_ = new WaitCondition(mutex_);
40  aborted_ = false;
41  queued_wait_until_.set_time(0, 0);
42 }
43 
44 /** Empty destructor. */
46 {
47 }
48 
49 void
51 {
52  fawkes::MutexLocker lock(mutex_);
53 
54  while (!queued_wait_until_.is_zero()) {
55  aborted_ = false;
56  bool woken = false;
57  fawkes::Time wait_until{queued_wait_until_};
58  queued_wait_until_.set_time(0, 0);
59 
60  do {
61  woken = waitcond_->abstimed_wait(wait_until.get_sec(), wait_until.get_nsec());
62  } while (woken && !aborted_);
63  if (!aborted_) {
64  lock.unlock();
65  listener_->timer_event();
66  }
67  }
68 }
69 
70 /** Start timer non-blocking.
71  * This starts a timer for an absolute timer.
72  * Invokes listener once timer is up.
73  * @param listener listener to notify on timer event
74  * @param wait_until point in time to wait for, must be in the future or timer event never occurs.
75  */
76 void
78 {
79  fawkes::MutexLocker lock(mutex_);
80  fawkes::Time now(Clock::instance());
81  if (waiting()) {
82  queued_wait_until_ = wait_until;
83  listener_ = listener;
84  wakeup();
85  } else {
86  // timer running, abort
87  queued_wait_until_ = wait_until;
88  aborted_ = true;
89  waitcond_->wake_all();
90  }
91 }
92 
93 /** Abort a currently running timer. */
94 void
96 {
97  mutex_->lock();
98  aborted_ = true;
99  waitcond_->wake_all();
100  mutex_->unlock();
101 }
PlexilTimerThread::loop
virtual void loop()
Code to execute in the thread.
Definition: timer_thread.cpp:50
fawkes::Mutex::lock
void lock()
Lock this mutex.
Definition: mutex.cpp:93
fawkes::Time::set_time
void set_time(const timeval *tv)
Sets the time.
Definition: time.cpp:253
fawkes::Mutex
Definition: mutex.h:38
fawkes::WaitCondition
Definition: wait_condition.h:42
fawkes::Thread::wakeup
void wakeup()
Wake up thread.
Definition: thread.cpp:1001
fawkes::MutexLocker
Definition: mutex_locker.h:39
PlexilTimerThread::PlexilTimerThread
PlexilTimerThread()
Constructor.
Definition: timer_thread.cpp:36
fawkes::Mutex::unlock
void unlock()
Unlock the mutex.
Definition: mutex.cpp:137
fawkes::WaitCondition::abstimed_wait
bool abstimed_wait(long int sec, long int nanosec)
Wait with absolute timeout.
Definition: wait_condition.cpp:175
fawkes
fawkes::Time::is_zero
bool is_zero() const
Definition: time.h:149
fawkes::WaitCondition::wake_all
void wake_all()
Wake up all waiting threads.
Definition: wait_condition.cpp:293
fawkes::Time
Definition: time.h:98
PlexilTimerThread::CallbackListener
Callback listener pure virtual class.
Definition: timer_thread.h:42
PlexilTimerThread::CallbackListener::timer_event
virtual void timer_event()=0
Called for timer events.
fawkes::Thread
Definition: thread.h:45
PlexilTimerThread::start_timer
void start_timer(CallbackListener *listener, const fawkes::Time &wait_until)
Start timer non-blocking.
Definition: timer_thread.cpp:77
fawkes::MutexLocker::unlock
void unlock()
Unlock the mutex.
Definition: mutex_locker.cpp:159
PlexilTimerThread::abort_timer
void abort_timer()
Abort a currently running timer.
Definition: timer_thread.cpp:95
fawkes::Thread::waiting
bool waiting() const
Check if thread is currently waiting for wakeup.
Definition: thread.cpp:863
PlexilTimerThread::~PlexilTimerThread
virtual ~PlexilTimerThread()
Empty destructor.
Definition: timer_thread.cpp:45