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
28using namespace fawkes;
29
30/** @class PlexilTimerThread "timer_thread.h"
31 * Timer support class.
32 * @author Tim Niemueller
33 */
34
35/** Constructor. */
36PlexilTimerThread::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
49void
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 */
76void
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. */
94void
96{
97 mutex_->lock();
98 aborted_ = true;
99 waitcond_->wake_all();
100 mutex_->unlock();
101}
Callback listener pure virtual class.
Definition: timer_thread.h:38
virtual void timer_event()=0
Called for timer events.
void start_timer(CallbackListener *listener, const fawkes::Time &wait_until)
Start timer non-blocking.
void abort_timer()
Abort a currently running timer.
virtual void loop()
Code to execute in the thread.
PlexilTimerThread()
Constructor.
virtual ~PlexilTimerThread()
Empty destructor.
Mutex locking helper.
Definition: mutex_locker.h:34
void unlock()
Unlock the mutex.
Mutex mutual exclusion lock.
Definition: mutex.h:33
void lock()
Lock this mutex.
Definition: mutex.cpp:87
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
Thread class encapsulation of pthreads.
Definition: thread.h:46
bool waiting() const
Check if thread is currently waiting for wakeup.
Definition: thread.cpp:857
void wakeup()
Wake up thread.
Definition: thread.cpp:995
A class for handling time.
Definition: time.h:93
bool is_zero() const
Check if time is zero.
Definition: time.h:143
void set_time(const timeval *tv)
Sets the time.
Definition: time.cpp:246
Wait until a given condition holds.
void wake_all()
Wake up all waiting threads.
bool abstimed_wait(long int sec, long int nanosec)
Wait with absolute timeout.
Fawkes library namespace.