summaryrefslogtreecommitdiff
path: root/src/components/include/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/include/utils')
-rw-r--r--src/components/include/utils/atomic_object.h112
-rw-r--r--src/components/include/utils/auto_trace.h6
-rw-r--r--src/components/include/utils/conditional_variable.h3
-rw-r--r--src/components/include/utils/custom_string.h218
-rw-r--r--src/components/include/utils/data_accessor.h18
-rw-r--r--src/components/include/utils/date_time.h30
-rw-r--r--src/components/include/utils/lock.h49
-rw-r--r--src/components/include/utils/logger.h220
-rw-r--r--src/components/include/utils/macro.h77
-rw-r--r--src/components/include/utils/make_shared.h143
-rw-r--r--src/components/include/utils/message_queue.h222
-rw-r--r--src/components/include/utils/messagemeter.h17
-rw-r--r--src/components/include/utils/prioritized_queue.h23
-rw-r--r--src/components/include/utils/push_log.h21
-rw-r--r--src/components/include/utils/rwlock.h48
-rw-r--r--src/components/include/utils/scope_guard.h326
-rw-r--r--src/components/include/utils/shared_ptr.h409
-rw-r--r--src/components/include/utils/threads/async_runner.h123
-rw-r--r--src/components/include/utils/threads/message_loop_thread.h62
-rw-r--r--src/components/include/utils/threads/thread.h14
-rw-r--r--src/components/include/utils/threads/thread_delegate.h13
-rw-r--r--src/components/include/utils/threads/thread_options.h7
-rw-r--r--src/components/include/utils/timer_thread.h449
23 files changed, 1497 insertions, 1113 deletions
diff --git a/src/components/include/utils/atomic_object.h b/src/components/include/utils/atomic_object.h
new file mode 100644
index 0000000000..257fcfbe3a
--- /dev/null
+++ b/src/components/include/utils/atomic_object.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * 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_INCLUDE_UTILS_ATOMIC_OBJECT_H_
+#define SRC_COMPONENTS_INCLUDE_UTILS_ATOMIC_OBJECT_H_
+
+#include "utils/rwlock.h"
+#include "utils/conditional_variable.h"
+#include "utils/macro.h"
+
+namespace sync_primitives {
+
+/**
+ * @brief Allows to safely change stored value from different threads.
+ *
+ * The usage example:
+ *
+ * threads::Atomic<int> i;
+ *
+ * i = 5; // here SDL is able to guarantee that this value will be safely
+ * // assigned even in multi threaded environment.
+ */
+template <typename T>
+class Atomic {
+ public:
+ /**
+ * @brief Atomic allows to construct atomic object.
+ * The operation is not atomic.
+ *
+ * @param value the value to initialize object with.
+ */
+ Atomic(const T& value) : value_(value) {}
+
+ /**
+ * @brief operator = thread safe setter for stored value.
+ *
+ * @param val value to assign.
+ *
+ * @return mofified value.
+ */
+ T& operator=(const T& val) {
+ sync_primitives::AutoWriteLock lock(rw_lock_);
+ value_ = val;
+ return value_;
+ }
+
+ /**
+ * @brief operator T thread safe getter
+ *
+ * return stored value.
+ */
+ operator T() const {
+ sync_primitives::AutoReadLock lock(rw_lock_);
+ return value_;
+ }
+
+ /**
+ * @brief operator T thread safe getter
+ *
+ * return stored value.
+ */
+ template <typename U>
+ operator U() const {
+ sync_primitives::AutoReadLock lock(rw_lock_);
+ return static_cast<U>(value_);
+ }
+
+ private:
+ T value_;
+ mutable sync_primitives::RWLock rw_lock_;
+};
+
+typedef Atomic<int> atomic_int;
+typedef Atomic<int32_t> atomic_int32;
+typedef Atomic<uint32_t> atomic_uint32;
+typedef Atomic<int64_t> atomic_int64;
+typedef Atomic<uint64_t> atomic_uint64;
+typedef Atomic<size_t> atomic_size_t;
+typedef Atomic<bool> atomic_bool;
+
+} // namespace sync_primitives
+
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_ATOMIC_OBJECT_H_
diff --git a/src/components/include/utils/auto_trace.h b/src/components/include/utils/auto_trace.h
index 87b6554808..36ff3be281 100644
--- a/src/components/include/utils/auto_trace.h
+++ b/src/components/include/utils/auto_trace.h
@@ -40,10 +40,8 @@ namespace logger {
class AutoTrace {
public:
- AutoTrace(
- log4cxx::LoggerPtr logger,
- const log4cxx::spi::LocationInfo& location
- );
+ AutoTrace(log4cxx::LoggerPtr logger,
+ const log4cxx::spi::LocationInfo& location);
~AutoTrace();
private:
diff --git a/src/components/include/utils/conditional_variable.h b/src/components/include/utils/conditional_variable.h
index 1f0a7e62de..f54a22e993 100644
--- a/src/components/include/utils/conditional_variable.h
+++ b/src/components/include/utils/conditional_variable.h
@@ -83,7 +83,8 @@ class ConditionalVariable {
// Wait forever or up to milliseconds time limit
bool Wait(AutoLock& auto_lock);
bool Wait(Lock& lock);
- WaitStatus WaitFor(AutoLock& auto_lock, int32_t milliseconds);
+ WaitStatus WaitFor(AutoLock& auto_lock, uint32_t milliseconds);
+
private:
impl::PlatformConditionalVariable cond_var_;
diff --git a/src/components/include/utils/custom_string.h b/src/components/include/utils/custom_string.h
new file mode 100644
index 0000000000..7b21e7a64d
--- /dev/null
+++ b/src/components/include/utils/custom_string.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * 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_INCLUDE_UTILS_CUSTOM_STRING_H_
+#define SRC_COMPONENTS_INCLUDE_UTILS_CUSTOM_STRING_H_
+
+#include <string>
+
+namespace utils {
+namespace custom_string {
+/* UTF8 formats:
+ * UTF8 1 byte consists from one-byte sequence
+ * bit representation of one character: 0xxxxxxx
+ * UTF8 2 bytes consists from two-byte sequence
+ * bit representation of one character: 110xxxxx 10xxxxxx
+ * UTF8 3 bytes consists from three-byte sequence
+ * bit representation of one character: 1110xxxx 10xxxxxx 10xxxxxx
+ * UTF8 4 bytes consists from four-byte sequence
+ * bit representation of one character: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ */
+enum UTFFormat {
+ kByteOfUTF8 = 0x80, // 10xxxxxx
+ kHigestByteOfUTF8Byte2 = 0xc0, // 110xxxxx
+ kHigestByteOfUTF8Byte3 = 0xe0, // 1110xxxx
+ kHigestByteOfUTF8Byte4 = 0xf0 // 11110xxx
+};
+
+class CustomString {
+ public:
+ /**
+ * @brief Constructs empty object.
+ */
+ CustomString();
+
+ /**
+ * @brief Constructs object with copy of str.
+ * @param Contains string for new object.
+ */
+ explicit CustomString(const std::string& str);
+
+ /**
+ * @brief Constructs object with copy of str.
+ * @param Contains pointer to string for new object.
+ */
+ explicit CustomString(const char* str);
+
+ /**
+ * @brief Constructs object with n consecutive copies of character c.
+ * @param Contains amount of copies of character for new object.
+ * @param Contains character for new object.
+ */
+ CustomString(size_t n, char c);
+
+ /**
+ * @brief Returns the length of the string, in terms of characters.
+ */
+ size_t size() const;
+
+ /**
+ * @brief Returns the length of the string, in terms of characters.
+ */
+ size_t length() const;
+
+ /**
+ * @brief Returns the length of the string, in terms of bytes.
+ */
+ size_t length_bytes() const;
+
+ /**
+ * @brief Returns TRUE if CustomString contains ASCII string
+ * otherwise returns FALSE.
+ */
+ bool is_ascii_string() const;
+
+ /**
+ * @brief Returns TRUE if CustomString contains empty string
+ * otherwise returns FALSE.
+ */
+ bool empty() const;
+
+ /**
+ * @brief Compares the value of the string (case sensitive).
+ * @param Contains string for comparing
+ * @return Returns TRUE if strings is equal otherwise returns FALSE.
+ */
+ bool operator==(const CustomString& str) const;
+
+ /**
+ * @brief Compares the value of the string (case sensitive).
+ * @param Contains string for comparing
+ * @return Returns TRUE if strings is equal otherwise returns FALSE.
+ */
+ bool operator==(const std::string& str) const;
+
+ /**
+ * @brief Assigns a new value to the string
+ * @param Contains string for assignment
+ * @return Returns result of assignment
+ */
+ CustomString& operator=(const char* str);
+
+ /**
+ * @brief Concatenates string from CustomString with string from argument.
+ * @param Contains string for concatenation.
+ * @return Returns result of concatenation.
+ */
+ CustomString operator+(const CustomString& str) const;
+
+ /**
+ * @brief Concatenates string from CustomString with string from argument.
+ * @param Contains string for concatenation.
+ * @return Returns result of concatenation.
+ */
+ CustomString operator+(const std::string& str) const;
+
+ /**
+ * @brief Returns the character at position pos in the string.
+ * Need to use with ASCII string.
+ * @param pos value with the position of a character within the string.
+ */
+ char at(size_t pos) const;
+
+ /**
+ * @brief Compares the value of the string (case sensitive).
+ * @param Contains string for comparing
+ * @return Returns 0 if strings is equal otherwise
+ * returns "<0" or ">0".
+ */
+ int compare(const char* str) const;
+
+ /**
+ * @brief Compares the value of the string (case sensitive).
+ * @param Contains string for comparing
+ * @return Returns 0 if strings is equal otherwise
+ * returns "<0" or ">0".
+ */
+ int compare(const std::string& str) const;
+
+ /**
+ * @brief Compares the value of the string (case insensitive).
+ * @param Contains string for comparing
+ * @return Returns TRUE if strings is equal otherwise returns FALSE.
+ */
+ bool CompareIgnoreCase(const CustomString& str) const;
+
+ /**
+ * @brief Compares the value of the string (case insensitive).
+ * @param Contains string for comparing
+ * @return Returns TRUE if strings is equal otherwise returns FALSE.
+ */
+ bool CompareIgnoreCase(const char* str) const;
+
+ /**
+ * @brief Returns a pointer to string from CustomString.
+ */
+ const char* c_str() const;
+
+ /**
+ * @brief Converts string to unicode string.
+ * @return Returns unicode string.
+ */
+ std::wstring ToWString() const;
+
+ /**
+ * @brief Returns copy of string as multibyte string.
+ */
+ std::string AsMBString() const;
+
+ /**
+ * @brief Converts string to lower case unicode string.
+ * @return Returns unicode string.
+ */
+ std::wstring ToWStringLowerCase() const;
+
+ private:
+ /**
+ * @brief Initiates members of CustomString
+ */
+ void InitData();
+
+ std::string mb_string_;
+ size_t amount_characters_;
+ bool is_ascii_string_;
+};
+
+} // namespace custom_string
+} // namespace utils
+
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_CUSTOM_STRING_H_
diff --git a/src/components/include/utils/data_accessor.h b/src/components/include/utils/data_accessor.h
index 344d6e34a8..9be28a638b 100644
--- a/src/components/include/utils/data_accessor.h
+++ b/src/components/include/utils/data_accessor.h
@@ -36,26 +36,24 @@
#include "utils/shared_ptr.h"
// This class is for thread-safe access to data
-template<class T>
+template <class T>
class DataAccessor {
public:
DataAccessor(const T& data, const sync_primitives::Lock& lock)
- : data_(data),
- lock_(const_cast<sync_primitives::Lock&>(lock)),
- counter_( new uint32_t(0)) {
+ : data_(data)
+ , lock_(const_cast<sync_primitives::Lock&>(lock))
+ , counter_(new uint32_t(0)) {
lock_.Acquire();
}
DataAccessor(const DataAccessor<T>& other)
- : data_(other.data_),
- lock_(other.lock_),
- counter_(other.counter_) {
+ : data_(other.data_), lock_(other.lock_), counter_(other.counter_) {
++(*counter_);
}
~DataAccessor() {
if (0 == *counter_) {
- lock_.Release();
+ lock_.Release();
} else {
--(*counter_);
}
@@ -63,9 +61,9 @@ class DataAccessor {
const T& GetData() const {
return data_;
}
- private:
- void *operator new(size_t size);
+ private:
+ void* operator new(size_t size);
const T& data_;
sync_primitives::Lock& lock_;
utils::SharedPtr<uint32_t> counter_;
diff --git a/src/components/include/utils/date_time.h b/src/components/include/utils/date_time.h
index c8cef32ef4..f8f8e3d6ce 100644
--- a/src/components/include/utils/date_time.h
+++ b/src/components/include/utils/date_time.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Ford Motor Company
+ * Copyright (c) 2015, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,17 +40,18 @@ typedef struct timeval TimevalStruct;
namespace date_time {
-enum TimeCompare {
- LESS,
- EQUAL,
- GREATER
-};
+enum TimeCompare { LESS, EQUAL, GREATER };
class DateTime {
public:
static const int32_t MILLISECONDS_IN_SECOND = 1000;
- static const int32_t MICROSECONDS_IN_MILLISECONDS = 1000;
- static const int32_t MICROSECONDS_IN_SECOND = 1000 * 1000;
+ static const int32_t MICROSECONDS_IN_MILLISECOND = 1000;
+ static const int32_t NANOSECONDS_IN_MICROSECOND = 1000;
+ static const int32_t SECONDS_IN_HOUR = 3600;
+ static const int32_t MICROSECONDS_IN_SECOND =
+ MILLISECONDS_IN_SECOND * MICROSECONDS_IN_MILLISECOND;
+ static const int32_t NANOSECONDS_IN_MILLISECOND =
+ MICROSECONDS_IN_MILLISECOND * NANOSECONDS_IN_MICROSECOND;
static TimevalStruct getCurrentTime();
@@ -69,6 +70,14 @@ class DateTime {
static int64_t calculateTimeDiff(const TimevalStruct& time1,
const TimevalStruct& time2);
+ /**
+ * @brief Adds milliseconds to time struct
+ * @param time contains time struct
+ * @param milliseconds contains value which need to
+ * add to time struct
+ **/
+ static void AddMilliseconds(TimevalStruct& time, uint32_t milliseconds);
+
static TimevalStruct Sub(const TimevalStruct& time1,
const TimevalStruct& time2);
@@ -78,9 +87,14 @@ class DateTime {
static bool Greater(const TimevalStruct& time1, const TimevalStruct& time2);
static bool Less(const TimevalStruct& time1, const TimevalStruct& time2);
static bool Equal(const TimevalStruct& time1, const TimevalStruct& time2);
+
+ private:
+ static TimevalStruct ConvertionUsecs(const TimevalStruct& time);
};
} // namespace date_time
bool operator<(const TimevalStruct& time1, const TimevalStruct& time2);
bool operator==(const TimevalStruct& time1, const TimevalStruct& time2);
+const TimevalStruct operator-(const TimevalStruct& time1,
+ const TimevalStruct& time2);
#endif // SRC_COMPONENTS_INCLUDE_UTILS_DATE_TIME_H_
diff --git a/src/components/include/utils/lock.h b/src/components/include/utils/lock.h
index 29bd467143..e615a58f9d 100644
--- a/src/components/include/utils/lock.h
+++ b/src/components/include/utils/lock.h
@@ -49,19 +49,21 @@ namespace impl {
#if defined(OS_POSIX)
typedef pthread_mutex_t PlatformMutex;
#endif
-} // namespace impl
-
+} // namespace impl
class SpinMutex {
public:
- SpinMutex()
- : state_(0) { }
+ SpinMutex() : state_(0) {}
void Lock() {
+ // Comment below add exception for lint error
+ // Reason: FlexeLint doesn't know about compiler's built-in instructions
+ /*lint -e1055*/
if (atomic_post_set(&state_) == 0) {
return;
}
- for(;;) {
+ for (;;) {
sched_yield();
+ /*lint -e1055*/
if (state_ == 0 && atomic_post_set(&state_) == 0) {
return;
}
@@ -70,8 +72,8 @@ class SpinMutex {
void Unlock() {
state_ = 0;
}
- ~SpinMutex() {
- }
+ ~SpinMutex() {}
+
private:
volatile unsigned int state_;
};
@@ -92,7 +94,7 @@ class SpinMutex {
class Lock {
public:
Lock();
- Lock(bool is_mutex_recursive);
+ Lock(bool is_recursive);
~Lock();
// Ackquire the lock. Must be called only once on a thread.
@@ -113,7 +115,8 @@ class Lock {
#ifndef NDEBUG
/**
- * @brief Basic debugging aid, a flag that signals wether this lock is currently taken
+ * @brief Basic debugging aid, a flag that signals wether this lock is
+ * currently taken
* Allows detection of abandoned and recursively captured mutexes
*/
uint32_t lock_taken_;
@@ -130,6 +133,7 @@ class Lock {
void AssertTakenAndMarkFree() {}
#endif
+ void Init(bool is_recursive);
friend class ConditionalVariable;
DISALLOW_COPY_AND_ASSIGN(Lock);
@@ -138,11 +142,17 @@ class Lock {
// This class is used to automatically acquire and release the a lock
class AutoLock {
public:
- explicit AutoLock(Lock& lock)
- : lock_(lock) { lock_.Acquire(); }
- ~AutoLock() { lock_.Release(); }
+ explicit AutoLock(Lock& lock) : lock_(lock) {
+ lock_.Acquire();
+ }
+ ~AutoLock() {
+ lock_.Release();
+ }
+
private:
- Lock& GetLock(){ return lock_; }
+ Lock& GetLock() {
+ return lock_;
+ }
Lock& lock_;
private:
@@ -154,9 +164,16 @@ class AutoLock {
// This class is used to temporarly unlock autolocked lock
class AutoUnlock {
public:
- explicit AutoUnlock(AutoLock& lock)
- : lock_(lock.GetLock()) { lock_.Release(); }
- ~AutoUnlock() { lock_.Acquire(); }
+ explicit AutoUnlock(Lock& lock) : lock_(lock) {
+ lock_.Release();
+ }
+ explicit AutoUnlock(AutoLock& lock) : lock_(lock.GetLock()) {
+ lock_.Release();
+ }
+ ~AutoUnlock() {
+ lock_.Acquire();
+ }
+
private:
Lock& lock_;
diff --git a/src/components/include/utils/logger.h b/src/components/include/utils/logger.h
index 50d194245c..11a2f1f0d9 100644
--- a/src/components/include/utils/logger.h
+++ b/src/components/include/utils/logger.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Ford Motor Company
+ * Copyright (c) 2015, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,157 +30,145 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-
-
-#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOGGER_H_
-#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOGGER_H_
+#ifndef SRC_COMPONENTS_INCLUDE_UTILS_LOGGER_H_
+#define SRC_COMPONENTS_INCLUDE_UTILS_LOGGER_H_
#ifdef ENABLE_LOG
- #include <errno.h>
- #include <string.h>
- #include <sstream>
- #include <log4cxx/propertyconfigurator.h>
- #include <log4cxx/spi/loggingevent.h>
- #include "utils/push_log.h"
- #include "utils/logger_status.h"
- #include "utils/auto_trace.h"
+#include <errno.h>
+#include <string.h>
+#include <sstream>
+#include <log4cxx/propertyconfigurator.h>
+#include <log4cxx/spi/loggingevent.h>
+#include "utils/push_log.h"
+#include "utils/logger_status.h"
+#include "utils/auto_trace.h"
#endif // ENABLE_LOG
#ifdef ENABLE_LOG
- #define CREATE_LOGGERPTR_GLOBAL(logger_var, logger_name) \
- namespace { \
- CREATE_LOGGERPTR_LOCAL(logger_var, logger_name); \
- }
-
- #define CREATE_LOGGERPTR_LOCAL(logger_var, logger_name) \
- log4cxx::LoggerPtr logger_var = log4cxx::LoggerPtr(log4cxx::Logger::getLogger(logger_name));
-
- #define INIT_LOGGER(file_name) \
- log4cxx::PropertyConfigurator::configure(file_name);
-
- // Logger deinitilization function and macro, need to stop log4cxx writing
- // without this deinitilization log4cxx threads continue using some instances destroyed by exit()
- void deinit_logger ();
- #define DEINIT_LOGGER() deinit_logger()
-
- #define LOG4CXX_IS_TRACE_ENABLED(logger) logger->isTraceEnabled()
-
- log4cxx_time_t time_now();
-
- #define LOG_WITH_LEVEL(loggerPtr, logLevel, logEvent) \
- do { \
- if (logger::logger_status != logger::DeletingLoggerThread) { \
- if (loggerPtr->isEnabledFor(logLevel)) { \
- std::stringstream accumulator; \
- accumulator << logEvent; \
- logger::push_log(loggerPtr, logLevel, accumulator.str(), time_now(), \
- LOG4CXX_LOCATION, ::log4cxx::spi::LoggingEvent::getCurrentThreadName()); \
- } \
- } \
- } while (false)
-
- #undef LOG4CXX_INFO
- #define LOG4CXX_INFO(loggerPtr, logEvent) LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getInfo(), logEvent)
-
- #define LOG4CXX_INFO_EXT(logger, logEvent) LOG4CXX_INFO(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
- #define LOG4CXX_INFO_STR_EXT(logger, logEvent) LOG4CXX_INFO_STR(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
-
- #define LOG4CXX_TRACE_EXT(logger, logEvent) LOG4CXX_TRACE(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
- #define LOG4CXX_TRACE_STR_EXT(logger, logEvent) LOG4CXX_TRACE_STR(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
-
- #undef LOG4CXX_DEBUG
- #define LOG4CXX_DEBUG(loggerPtr, logEvent) LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getDebug(), logEvent)
-
- #define LOG4CXX_DEBUG_EXT(logger, logEvent) LOG4CXX_DEBUG(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
- #define LOG4CXX_DEBUG_STR_EXT(logger, logEvent) LOG4CXX_DEBUG_STR(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
+#define CREATE_LOGGERPTR_GLOBAL(logger_var, logger_name) \
+ namespace { \
+ CREATE_LOGGERPTR_LOCAL(logger_var, logger_name); \
+ }
- #undef LOG4CXX_WARN
- #define LOG4CXX_WARN(loggerPtr, logEvent) LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getWarn(), logEvent)
+#define CREATE_LOGGERPTR_LOCAL(logger_var, logger_name) \
+ log4cxx::LoggerPtr logger_var = \
+ log4cxx::LoggerPtr(log4cxx::Logger::getLogger(logger_name));
- #define LOG4CXX_WARN_EXT(logger, logEvent) LOG4CXX_WARN(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
- #define LOG4CXX_WARN_STR_EXT(logger, logEvent) LOG4CXX_WARN_STR(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
+#define INIT_LOGGER(file_name, logs_enabled) \
+ log4cxx::PropertyConfigurator::configure(file_name); \
+ logger::set_logs_enabled(logs_enabled);
- #undef LOG4CXX_ERROR
- #define LOG4CXX_ERROR(loggerPtr, logEvent) LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getError(), logEvent)
+// Logger deinitilization function and macro, need to stop log4cxx writing
+// without this deinitilization log4cxx threads continue using some instances
+// destroyed by exit()
+void deinit_logger();
+#define DEINIT_LOGGER() deinit_logger()
- #define LOG4CXX_ERROR_EXT(logger, logEvent) LOG4CXX_ERROR(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
- #define LOG4CXX_ERROR_STR_EXT(logger, logEvent) LOG4CXX_ERROR_STR(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
+// special macros to dump logs from queue
+// it's need, for example, when crash happend
+#define FLUSH_LOGGER() logger::flush_logger()
- #undef LOG4CXX_FATAL
- #define LOG4CXX_FATAL(loggerPtr, logEvent) LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getFatal(), logEvent)
+#define LOG4CXX_IS_TRACE_ENABLED(logger) logger->isTraceEnabled()
- #define LOG4CXX_FATAL_EXT(logger, logEvent) LOG4CXX_FATAL(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
- #define LOG4CXX_FATAL_STR_EXT(logger, logEvent) LOG4CXX_FATAL_STR(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
+log4cxx_time_t time_now();
- #undef LOG4CXX_TRACE
- #define LOG4CXX_TRACE(loggerPtr, logEvent) LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getTrace(), logEvent)
+#define LOG_WITH_LEVEL(loggerPtr, logLevel, logEvent) \
+ do { \
+ if (logger::logs_enabled()) { \
+ if (logger::logger_status != logger::DeletingLoggerThread) { \
+ if (loggerPtr->isEnabledFor(logLevel)) { \
+ std::stringstream accumulator; \
+ accumulator << logEvent; \
+ logger::push_log( \
+ loggerPtr, \
+ logLevel, \
+ accumulator.str(), \
+ time_now(), \
+ LOG4CXX_LOCATION, \
+ ::log4cxx::spi::LoggingEvent::getCurrentThreadName()); \
+ } \
+ } \
+ } \
+ } while (false)
- #define LOG4CXX_AUTO_TRACE_WITH_NAME_SPECIFIED(loggerPtr, auto_trace) logger::AutoTrace auto_trace(loggerPtr, LOG4CXX_LOCATION)
- #define LOG4CXX_AUTO_TRACE(loggerPtr) LOG4CXX_AUTO_TRACE_WITH_NAME_SPECIFIED(loggerPtr, SDL_local_auto_trace_object)
+#undef LOG4CXX_TRACE
+#define LOG4CXX_TRACE(loggerPtr, logEvent) \
+ LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getTrace(), logEvent)
- #define LOG4CXX_ERROR_WITH_ERRNO(logger, message) \
- LOG4CXX_ERROR(logger, message << ", error code " << errno << " (" << strerror(errno) << ")")
+#define LOG4CXX_AUTO_TRACE_WITH_NAME_SPECIFIED(loggerPtr, auto_trace) \
+ logger::AutoTrace auto_trace(loggerPtr, LOG4CXX_LOCATION)
+#define LOG4CXX_AUTO_TRACE(loggerPtr) \
+ LOG4CXX_AUTO_TRACE_WITH_NAME_SPECIFIED(loggerPtr, SDL_local_auto_trace_object)
- #define LOG4CXX_WARN_WITH_ERRNO(logger, message) \
- LOG4CXX_WARN(logger, message << ", error code " << errno << " (" << strerror(errno) << ")")
+#undef LOG4CXX_DEBUG
+#define LOG4CXX_DEBUG(loggerPtr, logEvent) \
+ LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getDebug(), logEvent)
-#else // ENABLE_LOG is OFF
+#undef LOG4CXX_INFO
+#define LOG4CXX_INFO(loggerPtr, logEvent) \
+ LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getInfo(), logEvent)
- #define CREATE_LOGGERPTR_GLOBAL(logger_var, logger_name)
+#undef LOG4CXX_WARN
+#define LOG4CXX_WARN(loggerPtr, logEvent) \
+ LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getWarn(), logEvent)
- #define CREATE_LOGGERPTR_LOCAL(logger_var, logger_name)
+#undef LOG4CXX_ERROR
+#define LOG4CXX_ERROR(loggerPtr, logEvent) \
+ LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getError(), logEvent)
- #define INIT_LOGGER(file_name)
+#undef LOG4CXX_FATAL
+#define LOG4CXX_FATAL(loggerPtr, logEvent) \
+ LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getFatal(), logEvent)
- #define DEINIT_LOGGER(file_name)
+#define LOG4CXX_ERROR_WITH_ERRNO(loggerPtr, message) \
+ LOG4CXX_ERROR(loggerPtr, \
+ message << ", error code " << errno << " (" << strerror(errno) \
+ << ")")
- #define LOG4CXX_IS_TRACE_ENABLED(logger) false
+#define LOG4CXX_WARN_WITH_ERRNO(loggerPtr, message) \
+ LOG4CXX_WARN(loggerPtr, \
+ message << ", error code " << errno << " (" << strerror(errno) \
+ << ")")
- #undef LOG4CXX_INFO
- #define LOG4CXX_INFO(x,y)
+#else // ENABLE_LOG is OFF
- #undef LOG4CXX_WARN
- #define LOG4CXX_WARN(x,y)
+#define CREATE_LOGGERPTR_GLOBAL(logger_var, logger_name)
- #undef LOG4CXX_ERROR
- #define LOG4CXX_ERROR(x,y)
+#define CREATE_LOGGERPTR_LOCAL(logger_var, logger_name)
- #undef LOG4CXX_ERROR_WITH_ERRNO
- #define LOG4CXX_ERROR_WITH_ERRNO(x,y)
+#define INIT_LOGGER(file_name)
- #undef LOG4CXX_WARN_WITH_ERRNO
- #define LOG4CXX_WARN_WITH_ERRNO(x,y)
+#define DEINIT_LOGGER(file_name)
- #undef LOG4CXX_TRACE
- #define LOG4CXX_TRACE(x,y)
+#define LOG4CXX_IS_TRACE_ENABLED(logger) false
- #undef LOG4CXX_DEBUG
- #define LOG4CXX_DEBUG(x,y)
+#undef LOG4CXX_TRACE
+#define LOG4CXX_TRACE(x, y)
- #undef LOG4CXX_FATAL
- #define LOG4CXX_FATAL(x,y)
+#define LOG4CXX_AUTO_TRACE_WITH_NAME_SPECIFIED(loggerPtr, auto_trace)
+#define LOG4CXX_AUTO_TRACE(loggerPtr)
- #define LOG4CXX_INFO_EXT(logger, logEvent)
- #define LOG4CXX_INFO_STR_EXT(logger, logEvent)
+#undef LOG4CXX_DEBUG
+#define LOG4CXX_DEBUG(x, y)
- #define LOG4CXX_TRACE_EXT(logger, logEvent)
- #define LOG4CXX_TRACE_STR_EXT(logger, logEvent)
+#undef LOG4CXX_INFO
+#define LOG4CXX_INFO(x, y)
- #define LOG4CXX_DEBUG_EXT(logger, logEvent)
- #define LOG4CXX_DEBUG_STR_EXT(logger, logEvent)
+#undef LOG4CXX_WARN
+#define LOG4CXX_WARN(x, y)
- #define LOG4CXX_WARN_EXT(logger, logEvent)
- #define LOG4CXX_WARN_STR_EXT(logger, logEvent)
+#undef LOG4CXX_ERROR
+#define LOG4CXX_ERROR(x, y)
- #define LOG4CXX_ERROR_EXT(logger, logEvent)
- #define LOG4CXX_ERROR_STR_EXT(logger, logEvent)
+#undef LOG4CXX_ERROR_WITH_ERRNO
+#define LOG4CXX_ERROR_WITH_ERRNO(x, y)
- #define LOG4CXX_FATAL_EXT(logger, logEvent)
- #define LOG4CXX_FATAL_STR_EXT(logger, logEvent)
+#undef LOG4CXX_WARN_WITH_ERRNO
+#define LOG4CXX_WARN_WITH_ERRNO(x, y)
- #define LOG4CXX_AUTO_TRACE_WITH_NAME_SPECIFIED(loggerPtr, auto_trace)
- #define LOG4CXX_AUTO_TRACE(loggerPtr)
+#undef LOG4CXX_FATAL
+#define LOG4CXX_FATAL(x, y)
#endif // ENABLE_LOG
-#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOGGER_H_
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_LOGGER_H_
diff --git a/src/components/include/utils/macro.h b/src/components/include/utils/macro.h
index bfd13411f4..0e029e4b06 100644
--- a/src/components/include/utils/macro.h
+++ b/src/components/include/utils/macro.h
@@ -39,8 +39,8 @@
#endif
#include "logger.h"
-
-
+// A macro to set some action for variable to avoid "unused variable" warning
+#define UNUSED(x) (void) x;
// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
@@ -59,51 +59,60 @@
friend utils::deleters::Deleter<TypeName>::~Deleter()
#ifdef DEBUG
- #define ASSERT(condition) \
- do { \
- DEINIT_LOGGER(); \
- assert(condition); \
- } while (false)
+#define ASSERT(condition) \
+ FLUSH_LOGGER(); \
+ do { \
+ DEINIT_LOGGER(); \
+ assert(condition); \
+ } while (false)
#else // RELEASE
- #define ASSERT(condition) \
- fprintf(stderr, "Failed condition \"" #condition "\" [%s:%d][%s]\n\n", \
- __FILE__, __LINE__, __FUNCTION__)
+#define ASSERT(condition) \
+ fprintf(stderr, \
+ "Failed condition \"" #condition "\" [%s:%d][%s]\n\n", \
+ __FILE__, \
+ __LINE__, \
+ __FUNCTION__)
#endif
-#define DCHECK(condition) \
- if (!(condition)) { \
- CREATE_LOGGERPTR_LOCAL(logger_, "assert"); \
- LOG4CXX_FATAL(logger_, "DCHECK failed with \"" << #condition \
- << "\" [" << __FUNCTION__ << "][" << __FILE__ << ':' << __LINE__ << ']'); \
- ASSERT((condition)); \
+#define DCHECK(condition) \
+ if (!(condition)) { \
+ CREATE_LOGGERPTR_LOCAL(logger_, "Utils"); \
+ LOG4CXX_FATAL(logger_, \
+ "DCHECK failed with \"" << #condition << "\" [" \
+ << __FUNCTION__ << "][" << __FILE__ \
+ << ':' << __LINE__ << ']'); \
+ ASSERT((condition)); \
}
/*
* Will cauch assert on debug version,
* Will return return_value in release build
*/
-#define DCHECK_OR_RETURN(condition, return_value) \
- if (!(condition)) { \
- CREATE_LOGGERPTR_LOCAL(logger_, "assert"); \
- LOG4CXX_FATAL(logger_, "DCHECK failed with \"" << #condition \
- << "\" [" << __FUNCTION__ << "][" << __FILE__ << ':' << __LINE__ << ']' ); \
- ASSERT((condition)); \
- return (return_value); \
+#define DCHECK_OR_RETURN(condition, return_value) \
+ if (!(condition)) { \
+ CREATE_LOGGERPTR_LOCAL(logger_, "Utils"); \
+ LOG4CXX_FATAL(logger_, \
+ "DCHECK failed with \"" << #condition << "\" [" \
+ << __FUNCTION__ << "][" << __FILE__ \
+ << ':' << __LINE__ << ']'); \
+ ASSERT((condition)); \
+ return (return_value); \
}
/*
* Will cauch assert on debug version,
* Will return return_value in release build
*/
-#define DCHECK_OR_RETURN_VOID(condition) \
- if (!(condition)) { \
- CREATE_LOGGERPTR_LOCAL(logger_, "assert"); \
- LOG4CXX_FATAL(logger_, "DCHECK failed with \"" << #condition \
- << "\" [" << __FUNCTION__ << "][" << __FILE__ << ':' << __LINE__ << ']' ); \
- ASSERT((condition)); \
- return ; \
+#define DCHECK_OR_RETURN_VOID(condition) \
+ if (!(condition)) { \
+ CREATE_LOGGERPTR_LOCAL(logger_, "Utils"); \
+ LOG4CXX_FATAL(logger_, \
+ "DCHECK failed with \"" << #condition << "\" [" \
+ << __FUNCTION__ << "][" << __FILE__ \
+ << ':' << __LINE__ << ']'); \
+ ASSERT((condition)); \
+ return; \
}
-
#define NOTREACHED() DCHECK(!"Unreachable code")
// Allows to perform static check that virtual function from base class is
@@ -120,11 +129,11 @@
* @brief Calculate size of na array
* @param arr array, which size need to calculate
*/
-#define ARRAYSIZE(arr) sizeof (arr) / sizeof(*arr)
+#define ARRAYSIZE(arr) sizeof(arr) / sizeof(*arr)
#ifdef BUILD_TESTS
-#define FRIEND_TEST(test_case_name, test_name)\
-friend class test_case_name##_##test_name##_Test
+#define FRIEND_TEST(test_case_name, test_name) \
+ friend class test_case_name##_##test_name##_Test
#endif
#endif // SRC_COMPONENTS_INCLUDE_UTILS_MACRO_H_
diff --git a/src/components/include/utils/make_shared.h b/src/components/include/utils/make_shared.h
index dc817e362d..9d40d646a6 100644
--- a/src/components/include/utils/make_shared.h
+++ b/src/components/include/utils/make_shared.h
@@ -48,61 +48,144 @@
* SharedPtr<A> shared2(MakeShared<A>(5, 5.5);
* SharedPtr<A> shared3(MakeShared<A>(5, 5.5, std::string("MyStr"));
*
- * The profit in using MakeShared instead of simple allocation with operator new is evident.
- * Firstly it allows us to centralize allocation place, secondly it allows us to use
+ * The profit in using MakeShared instead of simple allocation with operator new
+ *is evident.
+ * Firstly it allows us to centralize allocation place, secondly it allows us to
+ *use
* safe operator new overloading (no throwable one).
*/
namespace utils {
-template <typename T> class SharedPtr;
+template <typename T>
+class SharedPtr;
namespace {
template <typename T>
- SharedPtr<T>Initialize(T* object) {
- return object == NULL ? SharedPtr<T>() : SharedPtr<T>(object);
- }
+SharedPtr<T> Initialize(T* object) {
+ return object == NULL ? SharedPtr<T>() : SharedPtr<T>(object);
+}
}
-template<typename T>
+template <typename T>
SharedPtr<T> MakeShared() {
T* t = new (std::nothrow) T;
return Initialize(t);
}
-template<typename T, typename Arg1>
+template <typename T, typename Arg1>
+SharedPtr<T> MakeShared(Arg1& arg1) {
+ T* t = new (std::nothrow) T(arg1);
+ return Initialize(t);
+}
+
+template <typename T, typename Arg1, typename Arg2>
+SharedPtr<T> MakeShared(Arg1& arg1, Arg2& arg2) {
+ T* t = new (std::nothrow) T(arg1, arg2);
+ return Initialize(t);
+}
+
+template <typename T, typename Arg1, typename Arg2, typename Arg3>
+SharedPtr<T> MakeShared(Arg1& arg1, Arg2& arg2, Arg3& arg3) {
+ T* t = new (std::nothrow) T(arg1, arg2, arg3);
+ return Initialize(t);
+}
+
+template <typename T,
+ typename Arg1,
+ typename Arg2,
+ typename Arg3,
+ typename Arg4>
+SharedPtr<T> MakeShared(Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4) {
+ T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4);
+ return Initialize(t);
+}
+
+template <typename T,
+ typename Arg1,
+ typename Arg2,
+ typename Arg3,
+ typename Arg4,
+ typename Arg5>
+SharedPtr<T> MakeShared(
+ Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4, Arg5& arg5) {
+ T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4, arg5);
+ return Initialize(t);
+}
+
+template <typename T,
+ typename Arg1,
+ typename Arg2,
+ typename Arg3,
+ typename Arg4,
+ typename Arg5,
+ typename Arg6>
+SharedPtr<T> MakeShared(
+ Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4, Arg5& arg5, Arg6& arg6) {
+ T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4, arg5, arg6);
+ return Initialize(t);
+}
+
+template <typename T, typename Arg1>
SharedPtr<T> MakeShared(const Arg1& arg1) {
- T* t = new (std::nothrow) T(arg1);
- return Initialize(t);
+ T* t = new (std::nothrow) T(arg1);
+ return Initialize(t);
}
-template<typename T, typename Arg1, typename Arg2>
+template <typename T, typename Arg1, typename Arg2>
SharedPtr<T> MakeShared(const Arg1& arg1, const Arg2& arg2) {
- T* t = new (std::nothrow) T(arg1, arg2);
- return Initialize(t);
+ T* t = new (std::nothrow) T(arg1, arg2);
+ return Initialize(t);
}
-template<typename T, typename Arg1, typename Arg2, typename Arg3>
+template <typename T, typename Arg1, typename Arg2, typename Arg3>
SharedPtr<T> MakeShared(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) {
- T* t = new (std::nothrow) T(arg1, arg2, arg3);
- return Initialize(t);
+ T* t = new (std::nothrow) T(arg1, arg2, arg3);
+ return Initialize(t);
}
-template<typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-SharedPtr<T> MakeShared(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) {
- T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4);
- return Initialize(t);
+template <typename T,
+ typename Arg1,
+ typename Arg2,
+ typename Arg3,
+ typename Arg4>
+SharedPtr<T> MakeShared(const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3,
+ const Arg4& arg4) {
+ T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4);
+ return Initialize(t);
}
-template<typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-SharedPtr<T> MakeShared(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) {
- T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4, arg5);
- return Initialize(t);
+template <typename T,
+ typename Arg1,
+ typename Arg2,
+ typename Arg3,
+ typename Arg4,
+ typename Arg5>
+SharedPtr<T> MakeShared(const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3,
+ const Arg4& arg4,
+ const Arg5& arg5) {
+ T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4, arg5);
+ return Initialize(t);
}
-template<typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
-SharedPtr<T> MakeShared(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5, const Arg6& arg6) {
- T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4, arg5, arg6);
- return Initialize(t);
+template <typename T,
+ typename Arg1,
+ typename Arg2,
+ typename Arg3,
+ typename Arg4,
+ typename Arg5,
+ typename Arg6>
+SharedPtr<T> MakeShared(const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3,
+ const Arg4& arg4,
+ const Arg5& arg5,
+ const Arg6& arg6) {
+ T* t = new (std::nothrow) T(arg1, arg2, arg3, arg4, arg5, arg6);
+ return Initialize(t);
}
-} // namespace utils;
-#endif // SRC_COMPONENTS_INCLUDE_UTILS_MAKE_SHARED_H_
+} // namespace utils;
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_MAKE_SHARED_H_
diff --git a/src/components/include/utils/message_queue.h b/src/components/include/utils/message_queue.h
index e0b3336728..093aa4cac2 100644
--- a/src/components/include/utils/message_queue.h
+++ b/src/components/include/utils/message_queue.h
@@ -34,10 +34,10 @@
#define SRC_COMPONENTS_INCLUDE_UTILS_MESSAGE_QUEUE_H_
#include <queue>
+#include <algorithm>
#include "utils/conditional_variable.h"
#include "utils/lock.h"
-#include "utils/logger.h"
#include "utils/prioritized_queue.h"
/**
@@ -47,151 +47,171 @@
namespace utils {
-template<typename T, class Q = std::queue<T> > class MessageQueue {
- public:
- typedef Q Queue;
- /**
- * \brief Default constructor
- */
- MessageQueue();
-
- /**
- * \brief Destructor
- */
- ~MessageQueue();
-
- /**
- * \brief Returns size of the queue.
- * \return Size of the queue.
- */
- size_t size() const;
-
- /**
- * \brief If queue is empty.
- * \return Is queue empty.
- */
- bool empty() const;
-
- /**
- * \brief Tells if queue is being shut down
- */
- bool IsShuttingDown() const;
-
- /**
- * \brief Adds element to the queue.
- * \param element Element to be added to the queue.n
- */
- void push(const T& element);
-
- /**
- * \brief Removes element from the queue and returns it.
- * \return To element of the queue.
- */
- T pop();
-
- /**
- * \brief Conditional wait.
- */
- void wait();
-
- /**
- * \brief Shutdown the queue.
- * This leads to waking up everyone waiting on the queue
- * Queue being shut down can be drained ( with pop() )
- * But nothing must be added to the queue after it began
- * shutting down
- */
- void Shutdown();
-
- /**
- * \brief Clears queue.
- */
- void Reset();
-
- private:
- /**
- *\brief Queue
- */
- Queue queue_;
- volatile bool shutting_down_;
-
- /**
- *\brief Platform specific syncronisation variable
- */
- mutable sync_primitives::Lock queue_lock_;
- sync_primitives::ConditionalVariable queue_new_items_;
+template <typename T, class Q = std::queue<T> >
+class MessageQueue {
+ public:
+ typedef Q Queue;
+ /**
+ * \brief Default constructor
+ */
+ MessageQueue();
+
+ /**
+ * \brief Destructor
+ */
+ ~MessageQueue();
+
+ /**
+ * \brief Returns size of the queue.
+ * \return Size of the queue.
+ */
+ size_t size() const;
+
+ /**
+ * \brief If queue is empty.
+ * \return Is queue empty.
+ */
+ bool empty() const;
+
+ /**
+ * \brief Tells if queue is being shut down
+ */
+ bool IsShuttingDown() const;
+
+ /**
+ * \brief Adds element to the queue.
+ * \param element Element to be added to the queue.n
+ */
+ void push(const T& element);
+
+ /**
+ * \brief Removes element from the queue and returns it
+ * \param element Element to be returned
+ * \return True on success, false if queue is empty
+ */
+ bool pop(T& element);
+
+ /**
+ * \brief Conditional wait.
+ */
+ void wait();
+
+ /**
+ * \brief waitUntilEmpty message queue
+ * Wait until message queue is empty
+ */
+ void WaitUntilEmpty();
+
+ /**
+ * \brief Shutdown the queue.
+ * This leads to waking up everyone waiting on the queue
+ * Queue being shut down can be drained ( with pop() )
+ * But nothing must be added to the queue after it began
+ * shutting down
+ */
+ void Shutdown();
+
+ /**
+ * \brief Clears queue.
+ */
+ void Reset();
+
+ private:
+ /**
+ *\brief Queue
+ */
+ Queue queue_;
+ volatile bool shutting_down_;
+
+ /**
+ *\brief Platform specific syncronisation variable
+ */
+ mutable sync_primitives::Lock queue_lock_;
+ sync_primitives::ConditionalVariable queue_new_items_;
};
-template<typename T, class Q> MessageQueue<T, Q>::MessageQueue()
- : shutting_down_(false) {
-}
+template <typename T, class Q>
+MessageQueue<T, Q>::MessageQueue()
+ : shutting_down_(false) {}
-template<typename T, class Q> MessageQueue<T, Q>::~MessageQueue() {
- if (!queue_.empty()) {
- CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
- LOG4CXX_ERROR(logger_, "Destruction of non-drained queue");
+template <typename T, class Q>
+MessageQueue<T, Q>::~MessageQueue() {}
+
+template <typename T, class Q>
+void MessageQueue<T, Q>::wait() {
+ sync_primitives::AutoLock auto_lock(queue_lock_);
+ while ((!shutting_down_) && queue_.empty()) {
+ queue_new_items_.Wait(auto_lock);
}
}
-template<typename T, class Q> void MessageQueue<T, Q>::wait() {
+template <typename T, class Q>
+void MessageQueue<T, Q>::WaitUntilEmpty() {
sync_primitives::AutoLock auto_lock(queue_lock_);
- while ((!shutting_down_) && queue_.empty()) {
+ while ((!shutting_down_) && !queue_.empty()) {
queue_new_items_.Wait(auto_lock);
}
}
-template<typename T, class Q> size_t MessageQueue<T, Q>::size() const {
+template <typename T, class Q>
+size_t MessageQueue<T, Q>::size() const {
sync_primitives::AutoLock auto_lock(queue_lock_);
return queue_.size();
}
-template<typename T, class Q> bool MessageQueue<T, Q>::empty() const {
+template <typename T, class Q>
+bool MessageQueue<T, Q>::empty() const {
sync_primitives::AutoLock auto_lock(queue_lock_);
return queue_.empty();
}
-template<typename T, class Q> bool MessageQueue<T, Q>::IsShuttingDown() const {
+template <typename T, class Q>
+bool MessageQueue<T, Q>::IsShuttingDown() const {
return shutting_down_;
}
-template<typename T, class Q> void MessageQueue<T, Q>::push(const T& element) {
+template <typename T, class Q>
+void MessageQueue<T, Q>::push(const T& element) {
{
sync_primitives::AutoLock auto_lock(queue_lock_);
if (shutting_down_) {
- CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
- LOG4CXX_ERROR(logger_, "Runtime error, pushing into queue"
- " that is being shut down");
- return;
+ return;
}
- queue_.push(element);
+ queue_.push(element);
}
queue_new_items_.Broadcast();
}
-template<typename T, class Q> T MessageQueue<T, Q>::pop() {
+template <typename T, class Q>
+bool MessageQueue<T, Q>::pop(T& element) {
sync_primitives::AutoLock auto_lock(queue_lock_);
if (queue_.empty()) {
- CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
- LOG4CXX_ERROR(logger_, "Runtime error, popping out of empty queue");
- NOTREACHED();
+ return false;
}
- T result = queue_.front();
+ element = queue_.front();
queue_.pop();
- return result;
+ queue_new_items_.NotifyOne();
+ return true;
}
-template<typename T, class Q> void MessageQueue<T, Q>::Shutdown() {
+template <typename T, class Q>
+void MessageQueue<T, Q>::Shutdown() {
sync_primitives::AutoLock auto_lock(queue_lock_);
shutting_down_ = true;
+ if (!queue_.empty()) {
+ Queue empty_queue;
+ std::swap(queue_, empty_queue);
+ }
queue_new_items_.Broadcast();
}
-template<typename T, class Q> void MessageQueue<T, Q>::Reset() {
+template <typename T, class Q>
+void MessageQueue<T, Q>::Reset() {
sync_primitives::AutoLock auto_lock(queue_lock_);
shutting_down_ = false;
if (!queue_.empty()) {
Queue empty_queue;
- queue_.swap(empty_queue);
+ std::swap(queue_, empty_queue);
}
}
diff --git a/src/components/include/utils/messagemeter.h b/src/components/include/utils/messagemeter.h
index a5d9968d81..42b658ad6b 100644
--- a/src/components/include/utils/messagemeter.h
+++ b/src/components/include/utils/messagemeter.h
@@ -94,7 +94,7 @@ class MessageMeter {
template <class Id>
MessageMeter<Id>::MessageMeter()
- : time_range_(TimevalStruct {0, 0}) {
+ : time_range_(TimevalStruct{0, 0}) {
time_range_.tv_sec = 1;
}
@@ -104,8 +104,7 @@ size_t MessageMeter<Id>::TrackMessage(const Id& id) {
}
template <class Id>
-size_t MessageMeter<Id>::TrackMessages(const Id& id,
- const size_t count) {
+size_t MessageMeter<Id>::TrackMessages(const Id& id, const size_t count) {
Timings& timings = timing_map_[id];
const TimevalStruct current_time = date_time::DateTime::getCurrentTime();
for (size_t i = 0; i < count; ++i) {
@@ -118,18 +117,16 @@ size_t MessageMeter<Id>::TrackMessages(const Id& id,
template <class Id>
size_t MessageMeter<Id>::Frequency(const Id& id) {
typename TimingMap::iterator it = timing_map_.find(id);
- if(it == timing_map_.end()) {
+ if (it == timing_map_.end()) {
return 0u;
}
Timings& timings = it->second;
if (timings.empty()) {
return 0u;
}
- const TimevalStruct actual_begin_time =
- date_time::DateTime::Sub(date_time::DateTime::getCurrentTime(),
- time_range_);
- timings.erase(timings.begin(),
- timings.upper_bound(actual_begin_time));
+ const TimevalStruct actual_begin_time = date_time::DateTime::Sub(
+ date_time::DateTime::getCurrentTime(), time_range_);
+ timings.erase(timings.begin(), timings.upper_bound(actual_begin_time));
return timings.size();
}
@@ -152,7 +149,7 @@ void MessageMeter<Id>::set_time_range(const size_t time_range_msecs) {
const size_t mSecs =
time_range_msecs % date_time::DateTime::MILLISECONDS_IN_SECOND;
time_range_.tv_usec =
- mSecs * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+ mSecs * date_time::DateTime::MICROSECONDS_IN_MILLISECOND;
}
template <class Id>
void MessageMeter<Id>::set_time_range(const TimevalStruct& time_range) {
diff --git a/src/components/include/utils/prioritized_queue.h b/src/components/include/utils/prioritized_queue.h
index 2a8ebf0a7b..eb4ba6a6c3 100644
--- a/src/components/include/utils/prioritized_queue.h
+++ b/src/components/include/utils/prioritized_queue.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
@@ -30,12 +30,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_PRIORITIZED_QUEUE_H_
-#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_PRIORITIZED_QUEUE_H_
+#ifndef SRC_COMPONENTS_INCLUDE_UTILS_PRIORITIZED_QUEUE_H_
+#define SRC_COMPONENTS_INCLUDE_UTILS_PRIORITIZED_QUEUE_H_
#include <queue>
#include <map>
-#include <iostream>
+#include <algorithm>
#include "utils/macro.h"
@@ -45,15 +45,13 @@ namespace utils {
* Template queue class that gives out messages respecting their priority
* Message class must have size_t PriorityOrder() method implemented
*/
-template < typename M >
+template <typename M>
class PrioritizedQueue {
public:
typedef M value_type;
// std::map guarantees it's contents is sorted by key
typedef std::map<size_t, std::queue<value_type> > QueuesMap;
- PrioritizedQueue()
- : total_size_(0) {
- }
+ PrioritizedQueue() : total_size_(0) {}
// All api mimics usual std queue interface
void push(const value_type& message) {
size_t message_priority = message.PriorityOrder();
@@ -66,6 +64,10 @@ class PrioritizedQueue {
bool empty() const {
return queues_.empty();
}
+ void swap(PrioritizedQueue<M>& x) {
+ std::swap(queues_, x.queues_);
+ std::swap(total_size_, x.total_size_);
+ }
value_type front() {
DCHECK(!queues_.empty() && !queues_.rbegin()->second.empty());
return queues_.rbegin()->second.front();
@@ -79,11 +81,12 @@ class PrioritizedQueue {
queues_.erase(last);
}
}
+
private:
QueuesMap queues_;
size_t total_size_;
};
-}
+} // namespace utils
-#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_PRIORITIZED_QUEUE_H_
diff --git a/src/components/include/utils/push_log.h b/src/components/include/utils/push_log.h
index 01389fb736..aaeaa83bae 100644
--- a/src/components/include/utils/push_log.h
+++ b/src/components/include/utils/push_log.h
@@ -38,15 +38,20 @@
namespace logger {
-bool push_log(
- log4cxx::LoggerPtr logger,
- log4cxx::LevelPtr level,
- const std::string& entry,
- log4cxx_time_t timeStamp,
- const log4cxx::spi::LocationInfo& location,
- const log4cxx::LogString& threadName
- );
+bool push_log(log4cxx::LoggerPtr logger,
+ log4cxx::LevelPtr level,
+ const std::string& entry,
+ log4cxx_time_t timeStamp,
+ const log4cxx::spi::LocationInfo& location,
+ const log4cxx::LogString& threadName);
+void flush_logger();
+
+bool logs_enabled();
+void set_logs_enabled(bool state);
+
+void create_log_message_loop_thread();
+void delete_log_message_loop_thread();
} // namespace logger
#endif // SRC_COMPONENTS_INCLUDE_UTILS_PUSH_LOG_H_
diff --git a/src/components/include/utils/rwlock.h b/src/components/include/utils/rwlock.h
index 1083dbd63f..b7e7484b48 100644
--- a/src/components/include/utils/rwlock.h
+++ b/src/components/include/utils/rwlock.h
@@ -51,10 +51,13 @@ typedef pthread_rwlock_t PlatformRWLock;
/**
* RW locks wrapper
- * Read-write locks permit concurrent reads and exclusive writes to a protected shared resource.
- * The read-write lock is a single entity that can be locked in read or write mode.
+ * Read-write locks permit concurrent reads and exclusive writes to a protected
+ * shared resource.
+ * The read-write lock is a single entity that can be locked in read or write
+ * mode.
* To modify a resource, a thread must first acquire the exclusive write lock.
- * An exclusive write lock is not permitted until all read locks have been released.
+ * An exclusive write lock is not permitted until all read locks have been
+ * released.
*/
class RWLock {
@@ -67,14 +70,19 @@ class RWLock {
* The calling thread acquires the read lock if a writer does not
* hold the lock and there are no writers blocked on the lock.
* It is unspecified whether the calling thread acquires the lock
- * when a writer does not hold the lock and there are writers waiting for the lock.
- * If a writer holds the lock, the calling thread will not acquire the read lock.
+ * when a writer does not hold the lock and there are writers waiting for the
+ * lock.
+ * If a writer holds the lock, the calling thread will not acquire the read
+ * lock.
* If the read lock is not acquired, the calling thread blocks
- * (that is, it does not return from the AcquireForReading()) until it can acquire the lock.
- * Results are undefined if the calling thread holds a write lock on rwlock at the time the call is made.
+ * (that is, it does not return from the AcquireForReading()) until it can
+ * acquire the lock.
+ * Results are undefined if the calling thread holds a write lock on rwlock at
+ * the time the call is made.
* A thread can hold multiple concurrent read locks on rwlock
* (that is, successfully call AcquireForReading() n times)
- * If so, the thread must perform matching unlocks (that is, it must call Release() n times).
+ * If so, the thread must perform matching unlocks (that is, it must call
+ * Release() n times).
* @returns true if lock was acquired and false if was not
*/
bool AcquireForReading();
@@ -91,9 +99,12 @@ class RWLock {
/**
* @brief Try to Acqure read-write lock for writing.
- * Applies a write lock like AcquireForWriting(), with the exception that the
- * function fails if any thread currently holds rwlock (for reading or writing)
- * Invoke of TryAcquireForWriting will not block calling thread and returns "false"
+ * Applies a write lock like AcquireForWriting(), with the exception that
+ * the
+ * function fails if any thread currently holds rwlock (for reading or
+ * writing)
+ * Invoke of TryAcquireForWriting will not block calling thread and returns
+ * "false"
* @returns true if lock was acquired and false if was not
*/
bool TryAcquireForWriting();
@@ -101,11 +112,13 @@ class RWLock {
/**
* @brief Acqure read-write lock for writing.
* Applies a write lock to the read-write lock.
- * The calling thread acquires the write lock if no other thread (reader or writer)
+ * The calling thread acquires the write lock if no other thread (reader or
+ * writer)
* holds the read-write lock rwlock. Otherwise, the thread blocks
* (that is, does not return from the AcquireForWriting() call)
* until it can acquire the lock.
- * Results are undefined if the calling thread holds the read-write lock (whether a read or write lock)
+ * Results are undefined if the calling thread holds the read-write lock
+ * (whether a read or write lock)
* at the time the call is made.
* The thread must perform matching unlock (that is, it must call Release()).
* @returns true if lock was acquired and false if was not
@@ -132,8 +145,7 @@ class RWLock {
class AutoReadLock {
public:
- explicit AutoReadLock(RWLock& rwlock)
- : rwlock_(rwlock) {
+ explicit AutoReadLock(RWLock& rwlock) : rwlock_(rwlock) {
rwlock_.AcquireForReading();
}
~AutoReadLock() {
@@ -147,12 +159,12 @@ class AutoReadLock {
/**
* @brief Makes auto lock read-write locks for writing
- * Please use AutoWriteLock to acquire for writing and (automatically) release it
+ * Please use AutoWriteLock to acquire for writing and (automatically) release
+ * it
*/
class AutoWriteLock {
public:
- explicit AutoWriteLock(RWLock& rwlock)
- : rwlock_(rwlock) {
+ explicit AutoWriteLock(RWLock& rwlock) : rwlock_(rwlock) {
rwlock_.AcquireForWriting();
}
~AutoWriteLock() {
diff --git a/src/components/include/utils/scope_guard.h b/src/components/include/utils/scope_guard.h
new file mode 100644
index 0000000000..bc60a7d288
--- /dev/null
+++ b/src/components/include/utils/scope_guard.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * 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_INCLUDE_UTILS_SCOPE_GUARD_H
+#define SRC_COMPONENTS_INCLUDE_UTILS_SCOPE_GUARD_H
+
+namespace utils {
+
+/**
+ * @brief The ScopeGuardImplBase class the class which allows to keep safety
+ * raw pointer within local scope. The same ScopeGuard has been provided by
+ * Andrej Alexandresku in the Loki library.
+ *
+ * The usage area example:
+ *
+ * Suppose user have to create some pointer in function call Init(). And in case
+ * of some fail condition this pointer has to be freed. So in order to avoid
+ * code duplicate as follows:
+ *
+ * bool SomeClass::Init() {
+ * memberObject_ = custom_allocate() // initialize member object with some
+ *value
+ * if(!some_condition) {
+ * custom_release(memberObject();
+ * return false;
+ * }
+ *
+ * if(!other_condition) {
+ * custom_release(memberObject)
+ * return false;
+ * }
+ * return true;
+ * }
+ *
+ * The user is able to use ScopeGuard, where possible to automatically call
+ * custom release function. See example bellow:
+ *
+ * bool SomeClass::Init() {
+ * memberObject_ = custom_allocate() // initialize member object with some
+ *value
+ * // The guard will call custom release function when it goes out of scope.
+ * ScopeGaurd guard = MakeGuard(custom_release, memberObject);
+ * if(!some_condition) {
+ * return false;
+ * }
+ *
+ * if(!other_condition) {
+ * return false;
+ * }
+ * // Here to avoid object releasing the user has to call Dismiss method.
+ * // So no custom release function will be called after return statement.
+ * guard.Dismiss();
+ * return true;
+ * }
+ */
+class ScopeGuardImplBase {
+ public:
+ /**
+ * @brief ScopeGuardImplBase the ScopeGuards constructor.
+ */
+ ScopeGuardImplBase() : dismissed_(false) {}
+
+ /**
+ * @brief Dismiss function which allows to dismiss releasing of stored object.
+ */
+ void Dismiss() const {
+ dismissed_ = true;
+ }
+
+ protected:
+ /**
+ * @brief ScopeGuardImplBase the copy constructor
+ *
+ * @param other the object that should be copied.
+ */
+ ScopeGuardImplBase(const ScopeGuardImplBase& other)
+ : dismissed_(other.dismissed_) {
+ other.Dismiss();
+ }
+
+ /**
+ * Allows to safely execute release function(i.e. it will be called only
+ * in case of releasing wasn't dismiss.)
+ */
+ template <typename T>
+ void SafeExecute(T& t) {
+ if (!t.dismissed_) {
+ t.Execute();
+ }
+ }
+
+ ~ScopeGuardImplBase() {}
+
+ mutable bool dismissed_;
+
+ private:
+ // Disallow copying via assign operator.
+ ScopeGuardImplBase& operator=(const ScopeGuardImplBase&);
+};
+
+/**
+ * The class which allows to bind some parameter with free function.
+ * I.E.
+ * void release(char* p){delete p;}
+ *
+ * ScopeGuard guard = MakeGuard(release, p);
+ *
+ * So the parameter p will be passed to the specified function.
+ */
+template <typename Function, typename Parameter1>
+class ScopeGuardImpl1 : public ScopeGuardImplBase {
+ public:
+ /**
+ * @brief MakeGuard allows to create ScopeGuard object.
+ *
+ * @param fun function to call, when out of scope.
+ *
+ * @param p1 parameter which will be passed to the certain function.
+ *
+ * @return ScopeGuard object.
+ */
+ static ScopeGuardImpl1<Function, Parameter1> MakeGuard(Function fun,
+ const Parameter1& p1) {
+ return ScopeGuardImpl1<Function, Parameter1>(fun, p1);
+ }
+
+ /**
+ Execute the SafeExecute function in destructor.
+ */
+ ~ScopeGuardImpl1() {
+ SafeExecute(*this);
+ }
+
+ protected:
+ /**
+ * @brief Execute allows to execute certain function with certain parameter.
+ */
+ void Execute() {
+ fun_(p1_);
+ }
+
+ /**
+ * @brief ScopeGuardImpl1 create ScopeGuard object.
+ *
+ * @param f function object.
+ *
+ * @param p1 parameter to to pass to the function object.
+ */
+ ScopeGuardImpl1(const Function& f, const Parameter1& p1) : fun_(f), p1_(p1) {}
+
+ private:
+ Function fun_;
+ const Parameter1 p1_;
+
+ friend class ScopeGuardImplBase;
+};
+
+/**
+ * The class which allows to call some member function in case of
+ * ScopeGuard object out of scope.
+ * I.E.
+ * vector<int> vec;
+ *
+ * // When function returns, the pop_back method for vector will be called.
+ * void foo() {
+ * ScopeGuard guard = MakeObjGuard(vec, &vector::pop_back);
+ * vec.push_back(5);
+ * }
+ */
+template <typename Obj, typename MemFun>
+class ObjScopeGuardImpl0 : public ScopeGuardImplBase {
+ public:
+ /**
+ * @brief MakeObjGuard creates ScopeGuard object.
+ *
+ * @param obj object whose method will be called.
+ *
+ * @param memFun the method to call.
+ *
+ * @return ScopeGuard object.
+ */
+ static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) {
+ return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
+ }
+
+ /**
+ Execute the SafeExecute function in destructor.
+ */
+ ~ObjScopeGuardImpl0() {
+ SafeExecute(*this);
+ }
+
+ protected:
+ /**
+ * @brief Execute allows to execute certain function with certain parameter.
+ */
+ void Execute() {
+ (obj_.*memFun_)();
+ }
+
+ /**
+ * @brief ObjScopeGuardImpl0 Create ScopeGuard object.
+ *
+ * @param obj object whose method will be called.
+ *
+ * @param memFun the method to call.
+ *
+ * @return ScopeGuard object.
+ */
+ ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun) {}
+
+ private:
+ Obj& obj_;
+ MemFun memFun_;
+ friend class ScopeGuardImplBase;
+};
+
+/**
+ * The class which allows to call some member function with certain parameter
+ * in case of ScopeGuard object out of scope.
+
+ */
+template <typename Obj, typename MemFun, typename Parameter1>
+class ObjScopeGuardImpl1 : public ScopeGuardImplBase {
+ public:
+ /**
+ * @brief MakeObjGuard creates ScopeGuard object.
+ *
+ * @param obj object whose method will be called.
+ *
+ * @param memFun the method to call.
+ *
+ * @param p1 the parameter to pass to the member function.
+ *
+ * @return ScopeGuard object.
+ */
+ static ObjScopeGuardImpl1<Obj, MemFun, Parameter1> MakeObjGuard(
+ Obj& obj, MemFun memFun, const Parameter1& p1) {
+ return ObjScopeGuardImpl1<Obj, MemFun, Parameter1>(obj, memFun, p1);
+ }
+
+ /**
+ Execute the SafeExecute function in destructor.
+ */
+ ~ObjScopeGuardImpl1() {
+ SafeExecute(*this);
+ }
+
+ protected:
+ /**
+ * @brief Execute allows to execute certain function with certain parameter.
+ */
+ void Execute() {
+ (obj_.*memFun_)(p1_);
+ }
+
+ /**
+ * @brief MakeObjGuard creates ScopeGuard object.
+ *
+ * @param obj object whose method will be called.
+ *
+ * @param memFun the method to call.
+ *
+ * @param p1 the parameter to pass to the member function.
+ *
+ * @return ScopeGuard object.
+ */
+ ObjScopeGuardImpl1(Obj& obj, MemFun memFun, const Parameter1& p1)
+ : obj_(obj), memFun_(memFun), p1_(p1) {}
+
+ private:
+ Obj& obj_;
+ MemFun memFun_;
+ const Parameter1 p1_;
+ friend class ScopeGuardImplBase;
+};
+
+typedef const ScopeGuardImplBase& ScopeGuard;
+
+template <typename F, typename P1>
+ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1) {
+ return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
+}
+
+template <typename Obj, typename MemFun>
+ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun) {
+ return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
+}
+
+template <typename Obj, typename MemFun, typename P1>
+ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj,
+ MemFun memFun,
+ const P1& p1) {
+ return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
+}
+}
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_SCOPE_GUARD_H
diff --git a/src/components/include/utils/shared_ptr.h b/src/components/include/utils/shared_ptr.h
index f506c6018e..064bb36b4a 100644
--- a/src/components/include/utils/shared_ptr.h
+++ b/src/components/include/utils/shared_ptr.h
@@ -41,6 +41,7 @@
#include "utils/atomic.h"
namespace utils {
+
/**
* @brief Shared pointer.
*
@@ -50,215 +51,228 @@ namespace utils {
*
* @tparam ObjectType Type of wrapped object.
**/
-template<typename ObjectType>
+template <typename ObjectType>
class SharedPtr {
- public:
- //std smart pointer compability
- typedef ObjectType element_type;
- /**
- * @brief Constructor.
- *
- * Initialize shared pointer with wrapped object.
- * Reference counter will be initialized to 1.
- *
- * @param Object Wrapped object.
- **/
- SharedPtr(ObjectType* Object);
-
- SharedPtr();
-
- /**
- * @brief Copy constructor.
- *
- * Initialize shared pointer with another shared pointer.
- * Reference counter will be incremented.
- *
- * @param Other Other shared pointer.
- **/
- SharedPtr(const SharedPtr<ObjectType>& Other);
-
- /**
- * @brief Copy constructor.
- *
- * Initialize shared pointer with another shared pointer.
- * Reference counter will be incremented.
- *
- * @tparam OtherObjectType Type of other object pointer. This
- * allows creating a shared pointer to an
- * intstance of a base class from a shared
- * pointer to an instance of a class
- * inherited from this base class.
- * If OtherObjectType is not implicitly
- * convertible to ObjectType it will
- * cause a compile error.
- *
- * @param Other Other shared pointer.
- **/
- template<typename OtherObjectType>
- SharedPtr(const SharedPtr<OtherObjectType>& Other);
-
- /**
- * @brief Destructor.
- *
- * Decrement reference counter and destroy wrapped object
- * if reference counter reaches zero.
- **/
- ~SharedPtr();
-
- /**
- * @brief Assignment operator.
- *
- * Drop reference to currently referenced object and add
- * reference to assigned object.
- *
- * @param Other Shared pointer to an object
- * that must be referenced.
- *
- * @return Reference to this shared pointer.
- **/
- SharedPtr<ObjectType>& operator =(const SharedPtr<ObjectType>& Other);
-
- bool operator ==(const SharedPtr<ObjectType>& Other) const;
-
- bool operator< (const SharedPtr<ObjectType>& other) const;
-
- /**
- * @brief Assignment operator.
- *
- * Drop reference to currently referenced object and add
- * reference to assigned object.
- *
- * @tparam OtherObjectType Type of other object pointer. This
- * allows creating a shared pointer to an
- * intstance of a base class from a shared
- * pointer to an instance of a class
- * inherited from this base class.
- * If OtherObjectType is not implicitly
- * convertible to ObjectType it will
- * cause a compile error.
- *
- * @param Other Shared pointer to an object
- * that must be referenced.
- *
- * @return Reference to this shared pointer.
- **/
- template<typename OtherObjectType>
- SharedPtr<ObjectType>& operator =(const SharedPtr<OtherObjectType>& Other);
-
- template<typename OtherObjectType>
- static SharedPtr<OtherObjectType> static_pointer_cast(
+ static void DummyDeleter(ObjectType* object_to_delete) {
+ delete object_to_delete;
+ }
+
+ public:
+ // std smart pointer compatibility
+ typedef ObjectType element_type;
+ typedef void (*Deleter)(ObjectType*);
+ /**
+ * @brief Constructor.
+ *
+ * Initialize shared pointer with wrapped object.
+ * Reference counter will be initialized to 1.
+ *
+ * @param Object Wrapped object.
+ **/
+ SharedPtr(ObjectType* Object);
+
+ SharedPtr(ObjectType* Object, Deleter deleter)
+ : mObject(Object)
+ , mReferenceCounter(new uint32_t(1))
+ , deleter_(deleter) {}
+
+ SharedPtr();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * Initialize shared pointer with another shared pointer.
+ * Reference counter will be incremented.
+ *
+ * @param Other Other shared pointer.
+ **/
+ SharedPtr(const SharedPtr<ObjectType>& Other);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * Initialize shared pointer with another shared pointer.
+ * Reference counter will be incremented.
+ *
+ * @tparam OtherObjectType Type of other object pointer. This
+ * allows creating a shared pointer to an
+ * intstance of a base class from a shared
+ * pointer to an instance of a class
+ * inherited from this base class.
+ * If OtherObjectType is not implicitly
+ * convertible to ObjectType it will
+ * cause a compile error.
+ *
+ * @param Other Other shared pointer.
+ **/
+ template <typename OtherObjectType>
+ SharedPtr(const SharedPtr<OtherObjectType>& Other);
+
+ /**
+ * @brief Destructor.
+ *
+ * Decrement reference counter and destroy wrapped object
+ * if reference counter reaches zero.
+ **/
+ ~SharedPtr();
+
+ /**
+ * @brief Assignment operator.
+ *
+ * Drop reference to currently referenced object and add
+ * reference to assigned object.
+ *
+ * @param Other Shared pointer to an object
+ * that must be referenced.
+ *
+ * @return Reference to this shared pointer.
+ **/
+ SharedPtr<ObjectType>& operator=(const SharedPtr<ObjectType>& Other);
+
+ bool operator==(const SharedPtr<ObjectType>& Other) const;
+
+ bool operator<(const SharedPtr<ObjectType>& other) const;
+
+ /**
+ * @brief Assignment operator.
+ *
+ * Drop reference to currently referenced object and add
+ * reference to assigned object.
+ *
+ * @tparam OtherObjectType Type of other object pointer. This
+ * allows creating a shared pointer to an
+ * intstance of a base class from a shared
+ * pointer to an instance of a class
+ * inherited from this base class.
+ * If OtherObjectType is not implicitly
+ * convertible to ObjectType it will
+ * cause a compile error.
+ *
+ * @param Other Shared pointer to an object
+ * that must be referenced.
+ *
+ * @return Reference to this shared pointer.
+ **/
+ template <typename OtherObjectType>
+ SharedPtr<ObjectType>& operator=(const SharedPtr<OtherObjectType>& Other);
+
+ template <typename OtherObjectType>
+ static SharedPtr<OtherObjectType> static_pointer_cast(
const SharedPtr<ObjectType>& pointer);
- template<typename OtherObjectType>
- static SharedPtr<OtherObjectType> dynamic_pointer_cast(
+ template <typename OtherObjectType>
+ static SharedPtr<OtherObjectType> dynamic_pointer_cast(
const SharedPtr<ObjectType>& pointer);
- /**
- * @brief Member access operator.
- *
- * @return Wrapped object.
- **/
- ObjectType* operator->() const;
-
- ObjectType& operator*() const;
- operator bool() const;
- void reset();
- void reset(ObjectType* other);
- ObjectType* get() const;
-
- /**
- * @return true if mObject not NULL
- */
- bool valid() const;
-
- private:
- void reset_impl(ObjectType* other);
-
- // TSharedPtr needs access to other TSharedPtr private members
- // for shared pointers type casts.
- template<typename OtherObjectType>
- friend class SharedPtr;
-
- /**
- * @brief Drop reference to wrapped object.
- *
- * If reference counter reaches zero object and its reference
- * counter will be deallocated.
- **/
- void dropReference();
-
- /**
- * @brief Wrapped object.
- **/
- ObjectType* mObject;
-
- /**
- * @brief Pointer to reference counter.
- **/
- uint32_t* mReferenceCounter;
-
- void release();
+ /**
+ * @brief Member access operator.
+ *
+ * @return Wrapped object.
+ **/
+ ObjectType* operator->() const;
+
+ ObjectType& operator*() const;
+ operator bool() const;
+ void reset();
+ void reset(ObjectType* other);
+ ObjectType* get() const;
+
+#ifdef BUILD_TESTS
+ inline const uint32_t* get_ReferenceCounter() const {
+ return mReferenceCounter;
+ }
+#endif // BUILD_TESTS
+
+ /**
+ * @return true if mObject not NULL
+ */
+ bool valid() const;
+
+ private:
+ void reset_impl(ObjectType* other);
+
+ // TSharedPtr needs access to other TSharedPtr private members
+ // for shared pointers type casts.
+ template <typename OtherObjectType>
+ friend class SharedPtr;
+
+ /**
+ * @brief Drop reference to wrapped object.
+ *
+ * If reference counter reaches zero object and its reference
+ * counter will be deallocated.
+ **/
+ void dropReference();
+
+ /**
+ * @brief Wrapped object.
+ **/
+ ObjectType* mObject;
+
+ /**
+ * @brief Pointer to reference counter.
+ **/
+ uint32_t* mReferenceCounter;
+
+ Deleter deleter_;
+ void release();
};
-template<typename ObjectType>
+template <typename ObjectType>
inline utils::SharedPtr<ObjectType>::SharedPtr(ObjectType* Object)
- : mObject(NULL),
- mReferenceCounter(new uint32_t(1)) {
+ : mObject(NULL)
+ , mReferenceCounter(new uint32_t(1))
+ , deleter_(DummyDeleter) {
DCHECK(Object != NULL);
mObject = Object;
}
-template<typename ObjectType>
+template <typename ObjectType>
inline utils::SharedPtr<ObjectType>::SharedPtr()
- : mObject(0),
- mReferenceCounter(0) {
-}
+ : mObject(0), mReferenceCounter(0), deleter_(DummyDeleter) {}
-template<typename ObjectType>
+template <typename ObjectType>
inline utils::SharedPtr<ObjectType>::SharedPtr(
- const SharedPtr<ObjectType>& Other)
- : mObject(0),
- mReferenceCounter(0) {
+ const SharedPtr<ObjectType>& Other)
+ : mObject(0), mReferenceCounter(0), deleter_(DummyDeleter) {
*this = Other;
}
-template<typename ObjectType>
-template<typename OtherObjectType>
+template <typename ObjectType>
+template <typename OtherObjectType>
inline utils::SharedPtr<ObjectType>::SharedPtr(
- const SharedPtr<OtherObjectType>& Other)
- : mObject(0),
- mReferenceCounter(0) {
+ const SharedPtr<OtherObjectType>& Other)
+ : mObject(0), mReferenceCounter(0), deleter_(DummyDeleter) {
*this = Other;
}
-template<typename ObjectType>
+template <typename ObjectType>
inline utils::SharedPtr<ObjectType>::~SharedPtr() {
dropReference();
}
-template<typename ObjectType>
-inline utils::SharedPtr<ObjectType>&
-utils::SharedPtr<ObjectType>::operator=(const SharedPtr<ObjectType>& Other) {
+template <typename ObjectType>
+inline utils::SharedPtr<ObjectType>& utils::SharedPtr<ObjectType>::operator=(
+ const SharedPtr<ObjectType>& Other) {
return operator=<ObjectType>(Other);
}
-template<typename ObjectType>
-inline bool utils::SharedPtr<ObjectType>::operator ==(
- const SharedPtr<ObjectType>& Other) const {
+template <typename ObjectType>
+inline bool utils::SharedPtr<ObjectType>::operator==(
+ const SharedPtr<ObjectType>& Other) const {
return (mObject == Other.mObject);
}
-template<typename ObjectType>
-inline bool utils::SharedPtr<ObjectType>::operator< (
- const SharedPtr<ObjectType>& other) const {
+template <typename ObjectType>
+inline bool utils::SharedPtr<ObjectType>::operator<(
+ const SharedPtr<ObjectType>& other) const {
return (mObject < other.mObject);
}
-template<typename ObjectType>
-template<typename OtherObjectType>
-inline utils::SharedPtr<ObjectType>&
-utils::SharedPtr<ObjectType>::operator=(
- const SharedPtr<OtherObjectType>& Other) {
+template <typename ObjectType>
+template <typename OtherObjectType>
+inline utils::SharedPtr<ObjectType>& utils::SharedPtr<ObjectType>::operator=(
+ const SharedPtr<OtherObjectType>& Other) {
dropReference();
mObject = Other.mObject;
@@ -271,9 +285,10 @@ utils::SharedPtr<ObjectType>::operator=(
return *this;
}
-template<typename ObjectType>
-template<typename OtherObjectType>
-utils::SharedPtr<OtherObjectType> utils::SharedPtr<ObjectType>::static_pointer_cast(const SharedPtr<ObjectType>& pointer) {
+template <typename ObjectType>
+template <typename OtherObjectType>
+utils::SharedPtr<OtherObjectType> utils::SharedPtr<
+ ObjectType>::static_pointer_cast(const SharedPtr<ObjectType>& pointer) {
SharedPtr<OtherObjectType> casted_pointer;
casted_pointer.mObject = static_cast<OtherObjectType*>(pointer.mObject);
casted_pointer.mReferenceCounter = pointer.mReferenceCounter;
@@ -285,9 +300,10 @@ utils::SharedPtr<OtherObjectType> utils::SharedPtr<ObjectType>::static_pointer_c
return casted_pointer;
}
-template<typename ObjectType>
-template<typename OtherObjectType>
-utils::SharedPtr<OtherObjectType> utils::SharedPtr<ObjectType>::dynamic_pointer_cast(const SharedPtr<ObjectType>& pointer) {
+template <typename ObjectType>
+template <typename OtherObjectType>
+utils::SharedPtr<OtherObjectType> utils::SharedPtr<
+ ObjectType>::dynamic_pointer_cast(const SharedPtr<ObjectType>& pointer) {
SharedPtr<OtherObjectType> casted_pointer;
casted_pointer.mObject = dynamic_cast<OtherObjectType*>(pointer.mObject);
if (NULL != casted_pointer.mObject) {
@@ -301,52 +317,51 @@ utils::SharedPtr<OtherObjectType> utils::SharedPtr<ObjectType>::dynamic_pointer_
return casted_pointer;
}
-template<typename ObjectType> ObjectType*
-utils::SharedPtr<ObjectType>::operator->() const {
+template <typename ObjectType>
+ObjectType* utils::SharedPtr<ObjectType>::operator->() const {
DCHECK(mObject);
return mObject;
}
-template<typename ObjectType> ObjectType&
-utils::SharedPtr<ObjectType>::operator*() const {
+template <typename ObjectType>
+ObjectType& utils::SharedPtr<ObjectType>::operator*() const {
DCHECK(mObject);
return *mObject;
}
-template<typename ObjectType>
+template <typename ObjectType>
utils::SharedPtr<ObjectType>::operator bool() const {
return valid();
}
-template<typename ObjectType> void
-utils::SharedPtr<ObjectType>::reset() {
+template <typename ObjectType>
+void utils::SharedPtr<ObjectType>::reset() {
reset_impl(0);
}
-template<typename ObjectType> void
-utils::SharedPtr<ObjectType>::reset(ObjectType* other) {
+template <typename ObjectType>
+void utils::SharedPtr<ObjectType>::reset(ObjectType* other) {
DCHECK(other != NULL);
reset_impl(other);
}
-template<typename ObjectType>
+template <typename ObjectType>
void SharedPtr<ObjectType>::release() {
-
- delete mObject;
+ deleter_(mObject);
mObject = 0;
delete mReferenceCounter;
mReferenceCounter = 0;
}
-template<typename ObjectType> void
-utils::SharedPtr<ObjectType>::reset_impl(ObjectType* other) {
+template <typename ObjectType>
+void utils::SharedPtr<ObjectType>::reset_impl(ObjectType* other) {
dropReference();
mObject = other;
mReferenceCounter = new uint32_t(1);
}
-template<typename ObjectType>
+template <typename ObjectType>
inline void SharedPtr<ObjectType>::dropReference() {
if (0 != mReferenceCounter) {
if (1 == atomic_post_dec(mReferenceCounter)) {
@@ -355,12 +370,12 @@ inline void SharedPtr<ObjectType>::dropReference() {
}
}
-template<typename ObjectType>
+template <typename ObjectType>
ObjectType* SharedPtr<ObjectType>::get() const {
return mObject;
}
-template<typename ObjectType>
+template <typename ObjectType>
inline bool SharedPtr<ObjectType>::valid() const {
if (mReferenceCounter && (0 < *mReferenceCounter)) {
return (mObject != NULL);
diff --git a/src/components/include/utils/threads/async_runner.h b/src/components/include/utils/threads/async_runner.h
index c3afe4eea0..c6da0638f4 100644
--- a/src/components/include/utils/threads/async_runner.h
+++ b/src/components/include/utils/threads/async_runner.h
@@ -52,76 +52,75 @@ namespace threads {
* is kind of manager for async functions.
*/
class AsyncRunner {
- public:
+ public:
+ /**
+ * @brief AsyncRunner constructor, allows to create and run new thread.
+ * The thread will be removed in destructor and appropriate delegate will
+ * be removed some time latter after pthred_join.
+ *
+ * @param thread_name thread's name.
+ *
+ * @param delegate delegate to run within thread.
+ */
+ explicit AsyncRunner(const std::string& thread_name);
+
+ /**
+ * @brief AsyncRun pass obtained delegate into internal queue
+ *
+ * @param delegate the objet which has to be concuremtly run
+ */
+ void AsyncRun(threads::ThreadDelegate* delegate);
+ /**
+ * @brief Stop delegates activity
+ */
+ void Stop();
+
+ ~AsyncRunner();
+
+ private:
+ class AsyncRunnerDelegate : public threads::ThreadDelegate {
+ public:
+ AsyncRunnerDelegate();
+
/**
- * @brief AsyncRunner constructor, allows to create and run new thread.
- * The thread will be removed in destructor and appropriate delegate will
- * be removed some time latter after pthred_join.
- *
- * @param thread_name thread's name.
- *
- * @param delegate delegate to run within thread.
+ * @brief threadMain runs delegates queue handling.
+ */
+ virtual void threadMain();
+
+ /**
+ * @brief exitThreadMain doing stuff before exit from thread.
*/
- explicit AsyncRunner(const std::string& thread_name);
+ virtual void exitThreadMain();
/**
- * @brief AsyncRun pass obtained delegate into internal queue
+ * @brief runDelegate push obtained delegate into specific queue
*
- * @param delegate the objet which has to be concuremtly run
+ * @param delegate object that has to be executed.
*/
- void AsyncRun(threads::ThreadDelegate* delegate);
+ void runDelegate(threads::ThreadDelegate* delegate);
+
+ private:
+ /**
+ * @brief processDelegate allows to pop delegate
+ * from queue and process it.
+ */
+ void processDelegate();
+
/**
- * @brief Stop delegates activity
+ * @brief waitForDelegate wait while delegates queue is empty.
*/
- void Stop();
-
- ~AsyncRunner();
-
- private:
-
- class AsyncRunnerDelegate: public threads::ThreadDelegate {
- public:
- AsyncRunnerDelegate();
-
- /**
- * @brief threadMain runs delegates queue handling.
- */
- virtual void threadMain();
-
- /**
- * @brief exitThreadMain doing stuff before exit from thread.
- */
- virtual void exitThreadMain();
-
- /**
- * @brief runDelegate push obtained delegate into specific queue
- *
- * @param delegate object that has to be executed.
- */
- void runDelegate(threads::ThreadDelegate* delegate);
-
- private:
- /**
- * @brief processDelegate allows to pop delegate
- * from queue and process it.
- */
- void processDelegate();
-
- /**
- * @brief waitForDelegate wait while delegates queue is empty.
- */
- void waitForDelegate();
-
- std::queue<threads::ThreadDelegate*> delegates_queue_;
- sync_primitives::ConditionalVariable delegate_notifier_;
- sync_primitives::Lock delegates_queue_lock_;
- volatile bool stop_flag_;
- };
-
- threads::Thread* thread_;
- AsyncRunnerDelegate* executor_;
+ void waitForDelegate();
+
+ std::queue<threads::ThreadDelegate*> delegates_queue_;
+ sync_primitives::ConditionalVariable delegate_notifier_;
+ sync_primitives::Lock delegates_queue_lock_;
+ volatile bool stop_flag_;
+ };
+
+ threads::Thread* thread_;
+ AsyncRunnerDelegate* executor_;
};
-} // namespace threads
+} // namespace threads
-#endif // SRC_COMPONENTS_INCLUDE_UTILS_ASYNC_RUNNER_H_
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_ASYNC_RUNNER_H_
diff --git a/src/components/include/utils/threads/message_loop_thread.h b/src/components/include/utils/threads/message_loop_thread.h
index 6f90df209c..15023f02dd 100644
--- a/src/components/include/utils/threads/message_loop_thread.h
+++ b/src/components/include/utils/threads/message_loop_thread.h
@@ -41,6 +41,7 @@
#include "utils/message_queue.h"
#include "utils/threads/thread.h"
#include "utils/shared_ptr.h"
+#include "utils/lock.h"
namespace threads {
@@ -52,7 +53,7 @@ using ::utils::MessageQueue;
* to it's queue. To handle messages someone, Handler must be implemented and
* passed to MessageLoopThread constructor.
*/
-template < class Q >
+template <class Q>
class MessageLoopThread {
public:
typedef Q Queue;
@@ -67,7 +68,8 @@ class MessageLoopThread {
* Method called by MessageLoopThread to process single message
* from it's queue. After calling this method message is discarded.
*/
- virtual void Handle(const Message message) = 0; // TODO(dchmerev): Use reference?
+ // TODO (AKozoriz) : change to const reference (APPLINK-20235)
+ virtual void Handle(const Message message) = 0;
virtual ~Handler() {}
};
@@ -86,12 +88,21 @@ class MessageLoopThread {
// Process already posted messages and stop thread processing. Thread-safe.
void Shutdown();
+ // Added for utils/test/auto_trace_test.cc
+ size_t GetMessageQueueSize() const;
+
+ /*
+ * Wait until message queue will be empty
+ */
+ void WaitDumpQueue();
+
private:
/*
* Implementation of ThreadDelegate that actually pumps the queue and is
* able to correctly shut it down
*/
- struct LoopThreadDelegate : public threads::ThreadDelegate {
+ class LoopThreadDelegate : public threads::ThreadDelegate {
+ public:
LoopThreadDelegate(MessageQueue<Message, Queue>* message_queue,
Handler* handler);
@@ -116,13 +127,17 @@ class MessageLoopThread {
///////// Implementation
-template<class Q>
-MessageLoopThread<Q>::MessageLoopThread(const std::string& name,
- Handler* handler,
+template <class Q>
+size_t MessageLoopThread<Q>::GetMessageQueueSize() const {
+ return message_queue_.size();
+}
+
+template <class Q>
+MessageLoopThread<Q>::MessageLoopThread(const std::string& name,
+ Handler* handler,
const ThreadOptions& thread_opts)
- : thread_delegate_(new LoopThreadDelegate(&message_queue_, handler)),
- thread_(threads::CreateThread(name.c_str(),
- thread_delegate_)) {
+ : thread_delegate_(new LoopThreadDelegate(&message_queue_, handler))
+ , thread_(threads::CreateThread(name.c_str(), thread_delegate_)) {
const bool started = thread_->start(thread_opts);
if (!started) {
CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
@@ -130,10 +145,9 @@ MessageLoopThread<Q>::MessageLoopThread(const std::string& name,
}
}
-template<class Q>
+template <class Q>
MessageLoopThread<Q>::~MessageLoopThread() {
Shutdown();
- thread_->join();
delete thread_delegate_;
threads::DeleteThread(thread_);
}
@@ -145,20 +159,24 @@ void MessageLoopThread<Q>::PostMessage(const Message& message) {
template <class Q>
void MessageLoopThread<Q>::Shutdown() {
- thread_->stop();
+ thread_->join();
+}
+
+template <class Q>
+void MessageLoopThread<Q>::WaitDumpQueue() {
+ message_queue_.WaitUntilEmpty();
}
//////////
-template<class Q>
+template <class Q>
MessageLoopThread<Q>::LoopThreadDelegate::LoopThreadDelegate(
MessageQueue<Message, Queue>* message_queue, Handler* handler)
- : handler_(*handler),
- message_queue_(*message_queue) {
+ : handler_(*handler), message_queue_(*message_queue) {
DCHECK(handler != NULL);
DCHECK(message_queue != NULL);
}
-template<class Q>
+template <class Q>
void MessageLoopThread<Q>::LoopThreadDelegate::threadMain() {
CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
LOG4CXX_AUTO_TRACE(logger_);
@@ -170,18 +188,20 @@ void MessageLoopThread<Q>::LoopThreadDelegate::threadMain() {
DrainQue();
}
-template<class Q>
+template <class Q>
void MessageLoopThread<Q>::LoopThreadDelegate::exitThreadMain() {
- CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
- LOG4CXX_AUTO_TRACE(logger_);
message_queue_.Shutdown();
}
-template<class Q>
+template <class Q>
void MessageLoopThread<Q>::LoopThreadDelegate::DrainQue() {
while (!message_queue_.empty()) {
- handler_.Handle(message_queue_.pop());
+ Message msg;
+ if (message_queue_.pop(msg)) {
+ handler_.Handle(msg);
+ }
}
}
+
} // namespace threads
#endif // SRC_COMPONENTS_INCLUDE_UTILS_THREADS_MESSAGE_LOOP_THREAD_H_
diff --git a/src/components/include/utils/threads/thread.h b/src/components/include/utils/threads/thread.h
index fd2b5e9fd9..c81b912e9a 100644
--- a/src/components/include/utils/threads/thread.h
+++ b/src/components/include/utils/threads/thread.h
@@ -119,12 +119,11 @@ class Thread {
return delegate_lock_;
}
- ThreadDelegate *delegate() const {
+ ThreadDelegate* delegate() const {
return delegate_;
}
- void set_delegate(ThreadDelegate *delegate) {
- DCHECK(!isThreadRunning_);
+ void set_delegate(ThreadDelegate* delegate) {
delegate_ = delegate;
}
@@ -132,6 +131,9 @@ class Thread {
friend void DeleteThread(Thread* thread);
public:
+ // Yield current thread
+ static void yield();
+
// Get unique ID of currently executing thread
static PlatformThreadHandle CurrentId();
@@ -195,6 +197,12 @@ class Thread {
}
/**
+ * @brief Checks if invoked in this Thread context
+ * @return True if called from this Thread class, false otherwise
+ */
+ bool IsCurrentThread() const;
+
+ /**
* @brief Thread options.
* @return thread options.
*/
diff --git a/src/components/include/utils/threads/thread_delegate.h b/src/components/include/utils/threads/thread_delegate.h
index 66ad30241c..2f2c8b3744 100644
--- a/src/components/include/utils/threads/thread_delegate.h
+++ b/src/components/include/utils/threads/thread_delegate.h
@@ -39,11 +39,7 @@
namespace threads {
-enum ThreadState {
- kInit = 0,
- kStarted = 1,
- kStopReq = 2
-};
+enum ThreadState { kInit = 0, kStarted = 1, kStopReq = 2 };
class Thread;
@@ -53,10 +49,7 @@ class Thread;
*/
class ThreadDelegate {
public:
- ThreadDelegate()
- : state_(kInit),
- thread_(NULL) {
- }
+ ThreadDelegate() : state_(kInit), thread_(NULL) {}
/**
* \brief Thread procedure.
*/
@@ -76,7 +69,7 @@ class ThreadDelegate {
return thread_;
}
- void set_thread(Thread *thread);
+ void set_thread(Thread* thread);
bool ImproveState(unsigned int to) {
state_lock_.Lock();
diff --git a/src/components/include/utils/threads/thread_options.h b/src/components/include/utils/threads/thread_options.h
index 797ee0693b..2f5c90ae44 100644
--- a/src/components/include/utils/threads/thread_options.h
+++ b/src/components/include/utils/threads/thread_options.h
@@ -51,15 +51,12 @@ class ThreadOptions {
* @param is_joinable - is thread joinable?
*/
explicit ThreadOptions(size_t stack_size = 0, bool is_joinable = true)
- : stack_size_(stack_size),
- is_joinable_(is_joinable) {
- }
+ : stack_size_(stack_size), is_joinable_(is_joinable) {}
/**
* Dtor.
*/
- virtual ~ThreadOptions() {
- }
+ virtual ~ThreadOptions() {}
/**
* Copy ctor.
diff --git a/src/components/include/utils/timer_thread.h b/src/components/include/utils/timer_thread.h
deleted file mode 100644
index 4236c4e46f..0000000000
--- a/src/components/include/utils/timer_thread.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (c) 2015, Ford Motor Company
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided with the
- * distribution.
- *
- * Neither the name of the Ford Motor Company nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * 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_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"
-#include "utils/logger.h"
-#include "utils/macro.h"
-#include "utils/timer_thread.h"
-#include "utils/threads/thread.h"
-#include "utils/threads/thread_delegate.h"
-
-namespace timer {
-// TODO(AKutsan): Remove this logger after bugfix
-CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
-
-class TimerDelegate;
-
-/**
- * \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:
- *
- * Create timer in mobile request
- *
- * timer::TimerThread<MobileRequest> timer(this, &MobileRequest::onTimeOut);
- * timer.start(10);
- *
- * some actions
- *
- * To stop timer call timer.stop();
- *
- */
-template<class T>
-class TimerThread {
- 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 Suspends timer execution after next loop.
- */
- virtual void suspend();
-
- /**
- * @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 timer_thread The Timer_thread pointer
- */
- explicit 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 void exitThreadMain();
-
- /**
- * @brief Set new Timeout
- * @param timeout_seconds New timeout to be set
- */
- virtual void setTimeOut(const uint32_t timeout_seconds);
-
- /**
- * @brief Quits threadMain function after next loop.
- */
- virtual void shouldBeStoped();
-
- /**
- * @brief Restarts non-loop timer after current iteration.
- */
- virtual void shouldBeRestarted();
-
- protected:
- TimerThread* timer_thread_;
- uint32_t timeout_seconds_;
- sync_primitives::Lock state_lock_;
- sync_primitives::ConditionalVariable termination_condition_;
- volatile bool stop_flag_;
- sync_primitives::Lock restart_flag_lock_;
- volatile bool restart_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 Default constructor
- *
- * @param timer_thread The Timer_thread pointer
- * @param timeout Timeout to be set
- */
- explicit TimerLooperDelegate(TimerThread* timer_thread);
-
- /**
- * @brief Thread main function.
- */
- 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),
- 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>
-TimerThread<T>::~TimerThread() {
- LOG4CXX_DEBUG(logger_, "TimerThread is to be destroyed " << name_);
- thread_->join();
- delete delegate_;
- threads::DeleteThread(thread_);
- callback_ = NULL;
- callee_ = NULL;
-}
-
-template<class T>
-void TimerThread<T>::start(uint32_t timeout_seconds) {
- LOG4CXX_AUTO_TRACE(logger_);
- if (isRunning()) {
- LOG4CXX_INFO(logger_, "Restart timer in thread " << name_);
- delegate_->shouldBeRestarted();
- updateTimeOut(timeout_seconds);
- } else {
- updateTimeOut(timeout_seconds);
- 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>
-void TimerThread<T>::stop() {
- LOG4CXX_AUTO_TRACE(logger_);
- DCHECK(thread_);
- LOG4CXX_DEBUG(logger_, "Stopping timer " << name_);
- thread_->join();
-}
-
-template<class T>
-bool TimerThread<T>::isRunning() {
- DCHECK(thread_);
- return thread_->is_running();
-}
-
-template<class T>
-void TimerThread<T>::suspend() {
- LOG4CXX_DEBUG(logger_, "Suspend timer " << name_ << " after next loop");
- delegate_->shouldBeStoped();
-}
-
-template<class T>
-void TimerThread<T>::updateTimeOut(const uint32_t timeout_seconds) {
- delegate_->setTimeOut(timeout_seconds);
-}
-
-template<class T> void TimerThread<T>::onTimeOut() const {
- if (callee_ && callback_) {
- (callee_->*callback_)();
- }
-}
-
-template<class T>
-TimerThread<T>::TimerDelegate::TimerDelegate(TimerThread* timer_thread)
- : timer_thread_(timer_thread),
- timeout_seconds_(0),
- state_lock_(true),
- stop_flag_(false),
- restart_flag_(false) {
- DCHECK(timer_thread_);
-}
-
-template<class T>
-TimerThread<T>::TimerLooperDelegate::TimerLooperDelegate(
- TimerThread* timer_thread)
- : TimerDelegate(timer_thread) {
-}
-
-template<class T>
-TimerThread<T>::TimerDelegate::~TimerDelegate() {
- timer_thread_ = NULL;
-}
-
-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();
- 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) {
- LOG4CXX_TRACE(logger_,
- "Timer timeout " << wait_milliseconds_left << " ms");
- timer_thread_->onTimeOut();
- } else {
- LOG4CXX_DEBUG(logger_,
- "Timeout reset force: " << TimerDelegate::timeout_seconds_);
- }
- {
- sync_primitives::AutoLock auto_lock(restart_flag_lock_);
- if (!restart_flag_) {
- return;
- }
- restart_flag_ = false;
- }
- }
-}
-
-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();
- ConditionalVariable::WaitStatus wait_status =
- 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 << " ms");
- TimerDelegate::timer_thread_->onTimeOut();
- } else {
- LOG4CXX_DEBUG(logger_,
- "Timeout reset force: " << TimerDelegate::timeout_seconds_);
- }
- }
-}
-
-template<class T>
-void TimerThread<T>::TimerDelegate::exitThreadMain() {
- shouldBeStoped();
- termination_condition_.NotifyOne();
-}
-
-template<class T>
-void TimerThread<T>::TimerDelegate::setTimeOut(const uint32_t timeout_seconds) {
- timeout_seconds_ = timeout_seconds;
- termination_condition_.NotifyOne();
-}
-
-template<class T>
-void TimerThread<T>::TimerDelegate::shouldBeStoped() {
- {
- sync_primitives::AutoLock auto_lock(state_lock_);
- stop_flag_ = true;
- }
- {
- sync_primitives::AutoLock auto_lock(restart_flag_lock_);
- restart_flag_ = false;
- }
-}
-
-template<class T>
-void TimerThread<T>::TimerDelegate::shouldBeRestarted() {
- sync_primitives::AutoLock auto_lock(restart_flag_lock_);
- restart_flag_ = true;
-}
-
-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
- 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 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_INCLUDE_UTILS_TIMER_THREAD_H_