summaryrefslogtreecommitdiff
path: root/src/components/include/utils/timer_thread.h
diff options
context:
space:
mode:
authorJustin Dickow <jjdickow@gmail.com>2015-02-20 09:11:18 -0500
committerJustin Dickow <jjdickow@gmail.com>2015-02-20 09:11:18 -0500
commita7c5d752cb75485baa0ded5226335d0f8eb10321 (patch)
treefbfd9251ada2cdcd5cf6a03a79887d08f6b496d7 /src/components/include/utils/timer_thread.h
parentb2b2233d866f102d3de339afa8ccaf37d3cf2570 (diff)
downloadsdl_core-a7c5d752cb75485baa0ded5226335d0f8eb10321.tar.gz
Bug Fixes and ImprovementsSynchronizationCommit
Fix Empty perform iteration request Fix type of name from string to enum SendLocation implemented on HTML5 HMI Fixed PI response on VR rejection due to high priority. Fix Apps not responsive/not able to start app/apps remain listed on SYNC even after USB disconnect Mobile API change and processing capabilities Change perform interaction request conditions. Fix SDL must always start 3sec timer before resuming the HMILevel of the app Remove redundant StartSavePersistentDataTimer() call. Change wrong predicate name to right. Added stream request handling feature Made streaming timeout in media manager configurable Put navi app in LIMITED in case of phone call Handling of audio state for applications Add stop streaming timeout into ini file Implement HMILevel resumption for job-1 Fix result code ABORTED when interrupts it by Voice recognition activation Fix incorrect value parameter unexpectedDisconnect in BCOnAppUnregistered Fix SDL send BC.OnAppUnregistered with "unexpectedDisconnect" set to "true" in case received from HMI OnExitAllApplications {"reason":"MASTER_RESET"} Fix Update ini file for iAP1 support Current working directory added to image path Fix helpers to make it workable with more then 2 parameters DCHECK() for ManageMobileCommand() replaced with log message because the latter returns false in some regular situations (e.g. TOO_MANY_PENDING_REQUESTS, see SDLAQ-CRS-10) Remove connection after closing. Signed-off-by: Justin Dickow <jjdickow@gmail.com>
Diffstat (limited to 'src/components/include/utils/timer_thread.h')
-rw-r--r--src/components/include/utils/timer_thread.h450
1 files changed, 241 insertions, 209 deletions
diff --git a/src/components/include/utils/timer_thread.h b/src/components/include/utils/timer_thread.h
index a3481e4b4b..eaa67effe2 100644
--- a/src/components/include/utils/timer_thread.h
+++ b/src/components/include/utils/timer_thread.h
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2013, Ford Motor Company
+/*
+ * Copyright (c) 2015, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,15 +28,16 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
-#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_TIMER_THREAD
-#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_TIMER_THREAD
+#ifndef SRC_COMPONENTS_INCLUDE_UTILS_TIMER_THREAD_H_
+#define SRC_COMPONENTS_INCLUDE_UTILS_TIMER_THREAD_H_
#include <time.h>
#include <inttypes.h>
#include <cstdint>
#include <limits>
+#include <string>
#include "utils/conditional_variable.h"
#include "utils/lock.h"
@@ -52,8 +53,9 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
class TimerDelegate;
-/*
- * The TimerThread class provide possibility to run timer in a separate thread.
+/**
+ * \class TimerThread
+ * \brief TimerThread class provide possibility to run timer in a separate thread.
* The client should specify callee and const callback function.
* Example usage:
*
@@ -67,315 +69,345 @@ class TimerDelegate;
* To stop timer call timer.stop();
*
*/
-template <class T>
+template<class T>
class TimerThread {
- public:
-
- friend class TimerDelegate;
- friend class TimerLooperDelegate;
-
+ public:
+ friend class TimerDelegate;
+ friend class TimerLooperDelegate;
+
+ /**
+ * @brief Default constructor
+ *
+ * @param name - display string to identify the thread.
+ * @param callee A class that use timer
+ * @param f CallBackFunction which will be called on timeout
+ * Attention! "f()" will be called not in main thread but in timer thread
+ * Never use stop() and start() methods inside f
+ * @param is_looper Define this timer as looper,
+ * if true, TimerThread will call "f()" function every time out
+ * until stop()
+ */
+ TimerThread(const char* name, T* callee, void (T::*f)(), bool is_looper =
+ false);
+
+ /**
+ * @brief Destructor
+ */
+ virtual ~TimerThread();
+
+ /**
+ * @brief Starts timer for specified timeout.
+ * Previously started timeout will be set to new value.
+ * On timeout TimerThread::onTimeOut interface will be called.
+ * Must not be used in callback function!
+ *
+ * @param timeout_seconds Timeout in seconds to be set
+ */
+ virtual void start(uint32_t timeout_seconds);
+
+ /**
+ * @brief Starts timer for specified timeout.
+ * Previously started timeout will be set to new value.
+ * On timeout TimerThread::onTimeOut interface will be called.
+ * Must not be used in callback function!
+ *
+ * @param timeout_seconds Timeout in seconds to be set
+ *
+ * @param callee A class that use timer
+ *
+ * @param allBackFunction which will be called on timeout
+ * Attention! "f()" will be called not in main thread but in timer thread
+ * Never use stop() and start() methods inside f
+ */
+ virtual void start(uint32_t timeout_seconds, T* callee, void (T::*f)());
+
+ /**
+ * @brief Stops timer execution
+ * Must not be used in callback function!
+ */
+ virtual void stop();
+
+ /**
+ * @brief Tell timer status
+ * @return true if timer is currently running, otherwise return false
+ */
+ virtual bool isRunning();
+
+ /**
+ * @brief method suspends timer execution
+ */
+ virtual void pause();
+
+ /**
+ * @brief Stop timer update timeout and start timer again
+ * Note that it cancel thread of timer, If you use it from callback,
+ * it probably will stop execution of callback function
+ * @param timeout_seconds new timeout value
+ *
+ */
+ virtual void updateTimeOut(const uint32_t timeout_seconds);
+
+ protected:
+ /**
+ * @brief Interface called by delegator on timeout
+ */
+ void onTimeOut() const;
+
+ private:
+ /**
+ * @brief Delegate release timer, will call callback function one time
+ */
+ class TimerDelegate : public threads::ThreadDelegate {
+ public:
/**
* @brief Default constructor
*
- * @param name - display string to identify the thread.
- * @param callee A class that use timer
- * @param f CallBackFunction which will be called on timeout
- * Attention! "f()" will be called not in main thread but in timer thread
- * Never use stop() and start() methods inside f
- * @param is_looper Define this timer as looper,
- * if true, TimerThread will call "f()" function every time out
- * until stop()
+ * @param timer_thread The Timer_thread pointer
*/
- TimerThread(const char* name, T* callee , void (T::*f)(), bool is_looper = false);
+ explicit TimerDelegate(TimerThread* timer_thread);
/**
* @brief Destructor
*/
- virtual ~TimerThread();
+ virtual ~TimerDelegate();
/**
- * @brief Starts timer for specified timeout.
- * Previously started timeout will be set to new value.
- * On timeout TimerThread::onTimeOut interface will be called.
- * Must not be used in callback function!
- *
- * @param timeout_seconds Timeout in seconds to be set
+ * @brief Thread main function.
*/
- virtual void start(uint32_t timeout_seconds);
+ virtual void threadMain();
/**
- * @brief Stops timer execution
- * Must not be used in callback function!
+ * @brief Called by thread::thread to free all allocated resources.
*/
- virtual void stop();
+ virtual void exitThreadMain();
/**
- * @brief Tell tmer status
- * @return true if timer is currently running, otherwise return false
+ * @brief Set new Timeout
+ * @param timeout_seconds New timeout to be set
*/
- virtual bool isRunning();
-
- /*
- * @brief Stop timer update timeout and start timer again
- * Note that it cancel thread of timer, If you use it from callback,
- * it probably will stop execution of callback function
- * @param timeout_seconds new timeout value
- *
- */
- virtual void updateTimeOut(const uint32_t timeout_seconds);
- threads::Thread* thread_;
- protected:
-
- /**
- * @brief Interface called by delegator on timeout
- */
- void onTimeOut() const;
-
- private:
-
+ virtual void setTimeOut(const uint32_t timeout_seconds);
+
+ protected:
+ TimerThread* timer_thread_;
+ uint32_t timeout_seconds_;
+ sync_primitives::Lock state_lock_;
+ sync_primitives::ConditionalVariable termination_condition_;
+ volatile bool stop_flag_;
+ int32_t calculateMillisecondsLeft();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TimerDelegate);
+ };
+
+ /**
+ * @brief Delegate release looper timer.
+ * Will call delegate every timeout function while stop()
+ * won't be called
+ */
+ class TimerLooperDelegate : public TimerDelegate {
+ public:
/**
- * @brief Delegate release timer, will call callback function one time
+ * @brief Default constructor
+ *
+ * @param timer_thread The Timer_thread pointer
+ * @param timeout Timeout to be set
*/
- class TimerDelegate : public threads::ThreadDelegate {
- public:
-
- /**
- * @brief Default constructor
- *
- * @param timer_thread The Timer_thread pointer
- */
- TimerDelegate(TimerThread* timer_thread);
-
- /**
- * @brief Destructor
- */
- virtual ~TimerDelegate();
-
- /**
- * @brief Thread main function.
- */
- virtual void threadMain();
-
- /**
- * @brief Called by thread::thread to free all allocated resources.
- */
- virtual bool exitThreadMain();
-
- /**
- * @brief Set new Timeout
- * @param timeout_seconds New timeout to be set
- */
- virtual void setTimeOut(const uint32_t timeout_seconds);
-
- protected:
- TimerThread* timer_thread_;
- uint32_t timeout_seconds_;
- sync_primitives::Lock state_lock_;
- sync_primitives::ConditionalVariable termination_condition_;
- volatile bool stop_flag_;
- int32_t calculateMillisecondsLeft();
- private:
- DISALLOW_COPY_AND_ASSIGN(TimerDelegate);
- };
-
+ explicit TimerLooperDelegate(TimerThread* timer_thread);
/**
- * @brief Delegate release looper timer.
- * Will call delegate every timeout function while stop()
- * won't be called
+ * @brief Thread main function.
*/
- class TimerLooperDelegate : public TimerDelegate {
- public:
-
- /**
- * @brief Default constructor
- *
- * @param timer_thread The Timer_thread pointer
- * @param timeout Timeout to be set
- */
- TimerLooperDelegate(TimerThread* timer_thread);
-
- /**
- * @brief Thread main function.
- */
- virtual void threadMain();
- private:
- DISALLOW_COPY_AND_ASSIGN(TimerLooperDelegate);
- };
- void (T::*callback_)();
- T* callee_;
- TimerDelegate* delegate_;
- //threads::Thread* thread_;
- std::string name_;
- mutable bool is_running_;
- bool is_looper_;
-
- DISALLOW_COPY_AND_ASSIGN(TimerThread);
+ virtual void threadMain();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TimerLooperDelegate);
+ };
+ threads::Thread* thread_;
+ void (T::*callback_)();
+ T* callee_;
+ TimerDelegate* delegate_;
+ std::string name_;
+ volatile bool is_looper_;
+
+ DISALLOW_COPY_AND_ASSIGN(TimerThread);
};
-template <class T>
-TimerThread<T>::TimerThread(const char* name, T* callee, void (T::*f)(), bool is_looper)
- : thread_(NULL),
- callback_(f),
- callee_(callee),
- delegate_(NULL),
- is_running_(false),
- is_looper_(is_looper) {
+template<class T>
+TimerThread<T>::TimerThread(const char* name, T* callee, void (T::*f)(),
+ bool is_looper)
+ : thread_(NULL),
+ callback_(f),
+ callee_(callee),
+ delegate_(NULL),
+ name_(name),
+ is_looper_(is_looper) {
+ delegate_ =
+ is_looper_ ? new TimerLooperDelegate(this) : new TimerDelegate(this);
+
+ thread_ = threads::CreateThread(name_.c_str(), delegate_);
}
-template <class T>
+template<class T>
TimerThread<T>::~TimerThread() {
- LOG4CXX_INFO(logger_, "TimerThread is to destroy " << name_);
- stop();
+ LOG4CXX_DEBUG(logger_, "TimerThread is to be destroyed " << name_);
+ thread_->join();
+ delete delegate_;
+ threads::DeleteThread(thread_);
callback_ = NULL;
callee_ = NULL;
}
-template <class T>
+template<class T>
void TimerThread<T>::start(uint32_t timeout_seconds) {
- LOG4CXX_TRACE(logger_, "Starting timer " << this);
- if (is_running_) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (isRunning()) {
LOG4CXX_INFO(logger_, "TimerThread start needs stop " << name_);
stop();
}
+ updateTimeOut(timeout_seconds);
+ thread_->start();
+}
- delegate_ = is_looper_ ?
- new TimerLooperDelegate(this) :
- new TimerDelegate(this);
- delegate_->setTimeOut(timeout_seconds);
-
- thread_ = threads::CreateThread("TimerThread", delegate_);
- if (delegate_ && thread_) {
- is_running_ = true;
- thread_->start();
- }
+template<class T>
+void TimerThread<T>::start(uint32_t timeout_seconds, T* callee,
+ void (T::*f)()) {
+ callee_ = callee;
+ callback_ = f;
+ start(timeout_seconds);
}
-template <class T>
+template<class T>
void TimerThread<T>::stop() {
- LOG4CXX_TRACE(logger_, "Stopping timer " << this);
- if (is_running_ && delegate_ && thread_) {
- LOG4CXX_INFO(logger_, "TimerThread thread_ stop " << name_);
- thread_->stop();
- is_running_ = false;
- } else {
- LOG4CXX_INFO(logger_, "TimerThread thread_ not stop " << name_);
- }
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(thread_);
+ LOG4CXX_DEBUG(logger_, "Stopping timer " << name_);
+ thread_->join();
}
-template <class T>
+template<class T>
bool TimerThread<T>::isRunning() {
- return is_running_;
+ DCHECK(thread_);
+ return thread_->is_running();
+}
+
+template<class T>
+void TimerThread<T>::pause() {
+ LOG4CXX_DEBUG(logger_, "Suspension of timer " << name_);
+ const uint32_t wait_seconds = std::numeric_limits<uint32_t>::max();
+ updateTimeOut(wait_seconds);
}
-template <class T>
+template<class T>
void TimerThread<T>::updateTimeOut(const uint32_t timeout_seconds) {
delegate_->setTimeOut(timeout_seconds);
}
-template <class T>
-void TimerThread<T>::onTimeOut() const {
+template<class T> void TimerThread<T>::onTimeOut() const {
if (callee_ && callback_) {
(callee_->*callback_)();
- /*
- if (!is_looper_) {
- stop();
- }
- */
}
}
-template <class T>
+template<class T>
TimerThread<T>::TimerDelegate::TimerDelegate(TimerThread* timer_thread)
- : timer_thread_(timer_thread),
- timeout_seconds_(0),
- state_lock_(true),
- stop_flag_(false) {
+ : timer_thread_(timer_thread),
+ timeout_seconds_(0),
+ state_lock_(true),
+ stop_flag_(false) {
DCHECK(timer_thread_);
}
-template <class T>
-TimerThread<T>::TimerLooperDelegate::TimerLooperDelegate(TimerThread* timer_thread)
- : TimerDelegate(timer_thread) {
+template<class T>
+TimerThread<T>::TimerLooperDelegate::TimerLooperDelegate(
+ TimerThread* timer_thread)
+ : TimerDelegate(timer_thread) {
}
-template <class T>
+template<class T>
TimerThread<T>::TimerDelegate::~TimerDelegate() {
timer_thread_ = NULL;
}
-template <class T>
+template<class T>
void TimerThread<T>::TimerDelegate::threadMain() {
using sync_primitives::ConditionalVariable;
sync_primitives::AutoLock auto_lock(state_lock_);
+ stop_flag_ = false;
while (!stop_flag_) {
// Sleep
- int32_t wait_milliseconds_left = TimerDelegate::calculateMillisecondsLeft();
+ int32_t wait_milliseconds_left = TimerDelegate::calculateMillisecondsLeft();
ConditionalVariable::WaitStatus wait_status =
termination_condition_.WaitFor(auto_lock, wait_milliseconds_left);
// Quit sleeping or continue sleeping in case of spurious wake up
- if (ConditionalVariable::kTimeout == wait_status ||
- wait_milliseconds_left <= 0) {
- break;
+ if (ConditionalVariable::kTimeout == wait_status
+ || wait_milliseconds_left <= 0) {
+ LOG4CXX_TRACE(logger_,
+ "Timer timeout " << wait_milliseconds_left << " ms");
+ timer_thread_->onTimeOut();
+ return;
+ } else {
+ LOG4CXX_DEBUG(logger_,
+ "Timeout reset force: " << TimerDelegate::timeout_seconds_);
+ return;
}
}
- if (!stop_flag_) {
- timer_thread_->onTimeOut();
- timer_thread_->stop();
- }
}
-template <class T>
+template<class T>
void TimerThread<T>::TimerLooperDelegate::threadMain() {
using sync_primitives::ConditionalVariable;
sync_primitives::AutoLock auto_lock(TimerDelegate::state_lock_);
+ TimerDelegate::stop_flag_ = false;
while (!TimerDelegate::stop_flag_) {
- int32_t wait_milliseconds_left = TimerDelegate::calculateMillisecondsLeft();
+ int32_t wait_milliseconds_left = TimerDelegate::calculateMillisecondsLeft();
ConditionalVariable::WaitStatus wait_status =
- TimerDelegate::termination_condition_.WaitFor(auto_lock, wait_milliseconds_left);
+ TimerDelegate::termination_condition_.WaitFor(auto_lock,
+ wait_milliseconds_left);
// Quit sleeping or continue sleeping in case of spurious wake up
- if (ConditionalVariable::kTimeout == wait_status ||
- wait_milliseconds_left <= 0) {
- LOG4CXX_TRACE(logger_, "Timer timeout " << wait_milliseconds_left);
+ if (ConditionalVariable::kTimeout == wait_status
+ || wait_milliseconds_left <= 0) {
+ LOG4CXX_TRACE(logger_,
+ "Timer timeout " << wait_milliseconds_left << " ms");
TimerDelegate::timer_thread_->onTimeOut();
} else {
- LOG4CXX_DEBUG(logger_, "Timeout reset force: " << TimerDelegate::timeout_seconds_);
+ LOG4CXX_DEBUG(logger_,
+ "Timeout reset force: " << TimerDelegate::timeout_seconds_);
}
}
}
-
-template <class T>
-bool TimerThread<T>::TimerDelegate::exitThreadMain() {
+template<class T>
+void TimerThread<T>::TimerDelegate::exitThreadMain() {
sync_primitives::AutoLock auto_lock(state_lock_);
stop_flag_ = true;
termination_condition_.NotifyOne();
- return true;
}
-template <class T>
+template<class T>
void TimerThread<T>::TimerDelegate::setTimeOut(const uint32_t timeout_seconds) {
timeout_seconds_ = timeout_seconds;
termination_condition_.NotifyOne();
}
-template <class T>
+template<class T>
int32_t TimerThread<T>::TimerThread::TimerDelegate::calculateMillisecondsLeft() {
time_t cur_time = time(NULL);
time_t end_time = std::numeric_limits<time_t>::max();
- if (TimerDelegate::timeout_seconds_ + cur_time > TimerDelegate::timeout_seconds_) { // no overflow occurred
+ if (TimerDelegate::timeout_seconds_ + cur_time
+ > TimerDelegate::timeout_seconds_) { // no overflow occurred
end_time = cur_time + TimerDelegate::timeout_seconds_;
}
- int64_t wait_seconds_left = static_cast<int64_t>(difftime(end_time, cur_time));
- int32_t wait_milliseconds_left = std::numeric_limits<int32_t>::max();
- const int32_t millisecconds_in_second = 1000;
- if (wait_seconds_left < std::numeric_limits<int32_t>::max() / millisecconds_in_second) {
- wait_milliseconds_left = millisecconds_in_second * wait_seconds_left;
+ int64_t wait_seconds_left = static_cast<int64_t>(difftime(end_time, cur_time));
+ int32_t wait_milliseconds_left = std::numeric_limits<int32_t>::max();
+ const int32_t milliseconds_in_second = 1000;
+ if (wait_seconds_left
+ < std::numeric_limits<int32_t>::max() / milliseconds_in_second) {
+ wait_milliseconds_left = milliseconds_in_second * wait_seconds_left;
}
return wait_milliseconds_left;
}
} // namespace timer
-#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_TIMER_THREAD
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_TIMER_THREAD_H_