add_library("Utils" ${SOURCES})
IF(${CMAKE_SYSTEM_NAME} MATCHES "QNX")
- target_link_libraries ("Utils" log4cxx apr-1 aprutil-1)
+ target_link_libraries("Utils" apr-1 aprutil-1)
else()
- target_link_libraries ("Utils" log4cxx apr-1 aprutil-1 rt)
+ target_link_libraries("Utils" apr-1 aprutil-1 rt)
endif()
+
+if(ENABLE_LOG)
+ target_link_libraries("Utils" log4cxx)
+endif()
+
-/**
-* \file request_watchdog.h
-* \brief DateTime class header file.
-*
-* Copyright (c) 2013, Ford Motor Company
+/*
+* Copyright (c) 2014, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
static const int32_t MICROSECONDS_IN_MILLISECONDS = 1000;
static TimevalStruct getCurrentTime();
- static int32_t calculateTimeSpan(TimevalStruct sinceTime);
+
+ // return MILLISECONDS count
+ static int64_t getmSecs(const TimevalStruct& time);
+ // return MICROSECONDS count
+ static int64_t getuSecs(const TimevalStruct& time);
+
+ // return MILLISECONDS count between sinceTime value and current time
+ static int64_t calculateTimeSpan(const TimevalStruct& sinceTime);
+
+ // return MILLISECONDS count between time1 and time2
+ static int64_t calculateTimeDiff(const TimevalStruct& time1,
+ const TimevalStruct& time2);
};
} // namespace date_time
#include <string>
#include <vector>
#include <iostream>
-#include "utils/logger.h"
namespace file_system {
/**
- * \file LOG4CXXLogger.hpp
- * \brief Definitions required by logger.
- * Stores device information
- *
- * Copyright (c) 2013, Ford Motor Company
+ * Copyright (c) 2014, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOGGER_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOGGER_H_
-#ifndef LOG4CXXLOGGER_HPP_
+#ifdef ENABLE_LOG
#include <errno.h>
#include <string.h>
#include <log4cxx/logger.h>
#include <log4cxx/propertyconfigurator.h>
+#endif // ENABLE_LOG
-namespace log4cxx
-{
-
+namespace log4cxx {
#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);
+
+ // without this line log4cxx threads continue using some instances destroyed by exit()
+ #define DEINIT_LOGGER() \
+ log4cxx::Logger::getRootLogger()->closeNestedAppenders();
+
#define LOG4CXX_IS_TRACE_ENABLED(logger) logger->isTraceEnabled()
#define LOG4CXX_INFO_EXT(logger, logEvent) LOG4CXX_INFO(logger, __PRETTY_FUNCTION__ << ": " << logEvent)
#define LOG4CXX_TRACE_EXIT(logger) LOG4CXX_TRACE(logger, "EXIT: " << __PRETTY_FUNCTION__ )
#define LOG4CXX_ERROR_WITH_ERRNO(logger, message) LOG4CXX_ERROR(logger, message << ", error code " << errno << " (" << strerror(errno) << ")")
-#else
+
+#else // ENABLE_LOG is OFF
+
+ #define CREATE_LOGGERPTR_GLOBAL(logger_var, logger_name)
+
+ #define CREATE_LOGGERPTR_LOCAL(logger_var, logger_name)
+
+ #define INIT_LOGGER(file_name)
+
+ #define DEINIT_LOGGER(file_name)
+
#define LOG4CXX_IS_TRACE_ENABLED(logger) false
#undef LOG4CXX_INFO
#define LOG4CXX_TRACE_ENTER(logger)
#define LOG4CXX_TRACE_EXIT(logger)
-
#endif // ENABLE_LOG
-}
-
-#define LOG4CXXLOGGER_HPP_
-
-#endif /* LOG4CXXLOGGER_HPP_ */
+} // namespace log4cxx
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOGGER_H_
template<typename T, class Q> MessageQueue<T, Q>::~MessageQueue() {
if (!queue_.empty()) {
- log4cxx::LoggerPtr logger =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
- LOG4CXX_ERROR(logger, "Destruction of non-drained queue");
+ CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
+ LOG4CXX_ERROR(logger_, "Destruction of non-drained queue");
}
}
template<typename T, class Q> void MessageQueue<T, Q>::push(const T& element) {
sync_primitives::AutoLock auto_lock(queue_lock_);
if (shutting_down_) {
- log4cxx::LoggerPtr logger =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
- LOG4CXX_ERROR(logger, "Runtime error, pushing into queue"
+ CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
+ LOG4CXX_ERROR(logger_, "Runtime error, pushing into queue"
" that is being shut down");
}
queue_.push(element);
template<typename T, class Q> T MessageQueue<T, Q>::pop() {
sync_primitives::AutoLock auto_lock(queue_lock_);
if (queue_.empty()) {
- log4cxx::LoggerPtr logger =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
- LOG4CXX_ERROR(logger, "Runtime error, popping out of empty que");
+ CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
+ LOG4CXX_ERROR(logger_, "Runtime error, popping out of empty que");
}
T result = queue_.front();
queue_.pop();
+/**
+ * Copyright (c) 2014, 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_UTILS_INCLUDE_MESSAGE_LOOP_THREAD_H_
#define SRC_COMPONENTS_UTILS_INCLUDE_MESSAGE_LOOP_THREAD_H_
: thread_(name.c_str(), new LoopThreadDelegate(&message_queue_, handler)) {
bool started = thread_.startWithOptions(thread_opts);
if (!started) {
- log4cxx::LoggerPtr logger =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
- LOG4CXX_ERROR(logger, "Failed to start thread " << name);
+ CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
+ LOG4CXX_ERROR(logger_, "Failed to start thread " << name);
}
}
#include <string>
#include "utils/macro.h"
-#include "utils/logger.h"
#include "utils/threads/thread_delegate.h"
#include "utils/threads/thread_options.h"
ThreadOptions thread_options_;
bool isThreadRunning_;
-#ifdef ENABLE_LOG
- static log4cxx::LoggerPtr logger_;
-#endif // ENABLE_LOG
-
private:
DISALLOW_COPY_AND_ASSIGN(Thread);
};
#include "utils/logger.h"
namespace {
-log4cxx::LoggerPtr g_logger =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
-
const long kNanosecondsPerSecond = 1000000000;
const long kMillisecondsPerSecond = 1000;
const long kNanosecondsPerMillisecond = 1000000;
namespace sync_primitives {
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
ConditionalVariable::ConditionalVariable() {
pthread_condattr_t attrs;
int32_t initialized = pthread_condattr_init(&attrs);
if (initialized != 0)
- LOG4CXX_ERROR(g_logger, "Failed to initialize "
+ LOG4CXX_ERROR(logger_, "Failed to initialize "
"conditional variable attributes");
pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC);
initialized = pthread_cond_init(&cond_var_, &attrs);
if (initialized != 0)
- LOG4CXX_ERROR(g_logger, "Failed to initialize "
+ LOG4CXX_ERROR(logger_, "Failed to initialize "
"conditional variable");
int32_t rv = pthread_condattr_destroy(&attrs);
if (rv != 0)
- LOG4CXX_ERROR(g_logger, "Failed to destroy "
+ LOG4CXX_ERROR(logger_, "Failed to destroy "
"conditional variable attributes");
}
void ConditionalVariable::NotifyOne() {
int32_t signaled = pthread_cond_signal(&cond_var_);
if (signaled != 0)
- LOG4CXX_ERROR(g_logger, "Failed to signal conditional variable");
+ LOG4CXX_ERROR(logger_, "Failed to signal conditional variable");
}
void ConditionalVariable::Broadcast() {
int32_t signaled = pthread_cond_broadcast(&cond_var_);
if (signaled != 0)
- LOG4CXX_ERROR(g_logger, "Failed to broadcast conditional variable");
+ LOG4CXX_ERROR(logger_, "Failed to broadcast conditional variable");
}
&lock.mutex_);
lock.AssertFreeAndMarkTaken();
if (wait_status != 0)
- LOG4CXX_ERROR(g_logger, "Failed to wait for conditional variable");
+ LOG4CXX_ERROR(logger_, "Failed to wait for conditional variable");
}
ConditionalVariable::WaitStatus ConditionalVariable::WaitFor(
wait_status = kTimeout;
} break;
default: {
- LOG4CXX_ERROR(g_logger, "Failed to timewait for conditional variable");
+ LOG4CXX_ERROR(logger_, "Failed to timewait for conditional variable");
}
}
-/**
-* \file request_watchdog.h
-* \brief DateTime class source file.
-*
-* Copyright (c) 2013, Ford Motor Company
+/*
+* Copyright (c) 2014, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
int32_t const DateTime::MILLISECONDS_IN_SECOND;
int32_t const DateTime::MICROSECONDS_IN_MILLISECONDS;
-struct timeval DateTime::getCurrentTime() {
- struct timeval currentTime;
- struct timezone timeZone;
+TimevalStruct DateTime::getCurrentTime() {
+ TimevalStruct currentTime;
+ timezone timeZone;
gettimeofday(¤tTime, &timeZone);
return currentTime;
}
-int32_t DateTime::calculateTimeSpan(struct timeval sinceTime) {
- struct timeval currentTime, timeDifference;
- struct timezone timeZone;
+int64_t DateTime::getmSecs(const TimevalStruct &time) {
+ return static_cast<int64_t>(time.tv_sec) * MILLISECONDS_IN_SECOND
+ + time.tv_usec / MICROSECONDS_IN_MILLISECONDS;
+}
- gettimeofday(¤tTime, &timeZone);
+int64_t DateTime::getuSecs(const TimevalStruct &time) {
+ return static_cast<int64_t>(time.tv_sec) * MILLISECONDS_IN_SECOND
+ * MICROSECONDS_IN_MILLISECONDS + time.tv_usec;
+}
- timeDifference.tv_sec = currentTime.tv_sec - sinceTime.tv_sec;
+int64_t DateTime::calculateTimeSpan(const TimevalStruct& sinceTime) {
+ return calculateTimeDiff(getCurrentTime(), sinceTime);
+}
- timeDifference.tv_usec = currentTime.tv_usec - sinceTime.tv_usec;
+int64_t DateTime::calculateTimeDiff(const TimevalStruct &time1,
+ const TimevalStruct &time2){
+ TimevalStruct timeDifference;
+ timeDifference.tv_sec = time1.tv_sec - time2.tv_sec;
+ timeDifference.tv_usec = time1.tv_usec - time2.tv_usec;
if ( timeDifference.tv_usec < 0 ) {
timeDifference.tv_sec--;
timeDifference.tv_usec += MILLISECONDS_IN_SECOND
* MICROSECONDS_IN_MILLISECONDS;
}
-
- return timeDifference.tv_sec * MILLISECONDS_IN_SECOND
- + timeDifference.tv_usec / MICROSECONDS_IN_MILLISECONDS;
+ return getmSecs(timeDifference);
}
} // namespace date_time
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sstream>
#include <dirent.h>
#include <unistd.h>
#include "utils/lock.h"
#include <errno.h>
+#include <stdint.h>
#include "utils/logger.h"
-namespace {
-log4cxx::LoggerPtr g_logger =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
-}
-
namespace sync_primitives {
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
Lock::Lock()
#ifndef NDEBUG
: lock_taken_(false)
{
int32_t status = pthread_mutex_init(&mutex_, NULL);
if (status != 0) {
- LOG4CXX_ERROR(g_logger, "Failed to initialize mutex");
+ LOG4CXX_ERROR(logger_, "Failed to initialize mutex");
}
}
Lock::~Lock() {
#ifndef NDEBUG
if (lock_taken_) {
- LOG4CXX_ERROR(g_logger, "Destroying non-released mutex");
+ LOG4CXX_ERROR(logger_, "Destroying non-released mutex");
}
#endif
int32_t status = pthread_mutex_destroy(&mutex_);
if (status != 0) {
- LOG4CXX_ERROR(g_logger, "Failed to destroy mutex");
+ LOG4CXX_ERROR(logger_, "Failed to destroy mutex");
}
}
void Lock::Ackquire() {
int32_t status = pthread_mutex_lock(&mutex_);
if (status != 0) {
- LOG4CXX_ERROR(g_logger, "Failed to acquire mutex");
+ LOG4CXX_ERROR(logger_, "Failed to acquire mutex");
}
AssertFreeAndMarkTaken();
}
AssertTakenAndMarkFree();
int32_t status = pthread_mutex_unlock(&mutex_);
if (status != 0) {
- LOG4CXX_ERROR(g_logger, "Failed to unlock mutex");
+ LOG4CXX_ERROR(logger_, "Failed to unlock mutex");
}
}
bool ackquired = false;
#ifndef NDEBUG
if (lock_taken_) {
- LOG4CXX_ERROR(g_logger, "Trying to lock already taken mutex");
+ LOG4CXX_ERROR(logger_, "Trying to lock already taken mutex");
}
#endif
switch(pthread_mutex_trylock(&mutex_)) {
} break;
default: {
ackquired = false;
- LOG4CXX_ERROR(g_logger, "Failed to try lock the mutex");
+ LOG4CXX_ERROR(logger_, "Failed to try lock the mutex");
}
}
return ackquired;
#ifndef NDEBUG
void Lock::AssertFreeAndMarkTaken() {
if (lock_taken_) {
- LOG4CXX_ERROR(g_logger, "Locking already taken mutex");
+ LOG4CXX_ERROR(logger_, "Locking already taken mutex");
}
lock_taken_ = true;
}
void Lock::AssertTakenAndMarkFree() {
if (!lock_taken_) {
- LOG4CXX_ERROR(g_logger, "Unlocking a mutex that is not taken");
+ LOG4CXX_ERROR(logger_, "Unlocking a mutex that is not taken");
}
lock_taken_ = false;
}
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <errno.h>
+
#include <limits.h>
#include <stddef.h>
#include "utils/threads/thread.h"
#include "utils/threads/thread_manager.h"
+#include "utils/logger.h"
using namespace std;
using namespace threads::impl;
}
namespace threads {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "threads::Thread")
+
size_t Thread::kMinStackSize = PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */
-#ifdef ENABLE_LOG
-log4cxx::LoggerPtr Thread::logger_ =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("threads::Thread"));
-#endif // ENABLE_LOG
bool Thread::Id::operator==(const Thread::Id other) const {
return pthread_equal(id_, other.id_) != 0;
namespace threads {
-namespace {
-
-log4cxx::LoggerPtr logger_ =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("threads::PulseThreadDelegate"));
-
-} // anonimous namespace
+CREATE_LOGGERPTR_GLOBAL(logger_, "threads::PulseThreadDelegate")
PulseThreadDelegate::PulseThreadDelegate() : run_(false) {
LOG4CXX_TRACE(logger_, "Creating QNX channel");
}
}
else {
- LOG4CXX_WARN(logger_, "Error occured while waiting for pulse on QNX channel " << chid_);
+ if (run_) {
+ LOG4CXX_WARN(logger_, "Error occured while waiting for pulse on QNX channel " << chid_);
+ }
+ else {
+ LOG4CXX_INFO(logger_, "QNX channel " << chid_ << " is apparently destroyed");
+ }
}
}
}
*/
#include "utils/threads/thread_manager.h"
+#include "utils/logger.h"
#include <sstream>
using namespace std;
using namespace sync_primitives;
-namespace {
-
-const char* kUnknownName = "UnnamedThread";
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
-log4cxx::LoggerPtr g_logger =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
-
-} // namespace
+namespace {
+ const char* kUnknownName = "UnnamedThread";
+}
UnnamedThreadRegistry::UnnamedThreadRegistry() {
-
}
UnnamedThreadRegistry::~UnnamedThreadRegistry() {
-
}
std::string UnnamedThreadRegistry::GetUniqueName(PlatformThreadHandle id) {
pair<IdNamesMap::iterator, bool> inserted =
id_names_.insert(make_pair(id, name));
if (!inserted.second) {
- LOG4CXX_ERROR(g_logger, "Trying to register thread name " << name
+ LOG4CXX_ERROR(logger_, "Trying to register thread name " << name
<<", but it is already registered with name "
<<inserted.first->second);
}
} else {
- LOG4CXX_ERROR(g_logger, "Ignoring duplicate thread name: " + name);
+ LOG4CXX_ERROR(logger_, "Ignoring duplicate thread name: " + name);
}
}
if (found != id_names_.end()) {
return found->second;
} else {
- LOG4CXX_WARN(g_logger, "Thread doesn't have associated name");
+ LOG4CXX_WARN(logger_, "Thread doesn't have associated name");
return unnamed_thread_namer_.GetUniqueName(id);
}
}
id_names_.erase(id);
}
-
} // namespace impl
} // namespace threads
namespace threads {
-namespace {
-log4cxx::LoggerPtr g_logger =
- log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
-}
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
SingleThreadSimpleValidator::SingleThreadSimpleValidator()
: creation_thread_id_(Thread::CurrentId()) {
void SingleThreadSimpleValidator::AssertRunningOnCreationThread() const {
Thread::Id current_id = Thread::CurrentId();
if (creation_thread_id_ != current_id) {
- LOG4CXX_ERROR(g_logger, "Single-threaded object created at thread "
+ LOG4CXX_ERROR(logger_, "Single-threaded object created at thread "
<< creation_thread_id_
<<" is accessed from thread "
<< current_id
void SingleThreadValidator::AssertRunningOnValidThread() const {
Thread::Id current_id = Thread::CurrentId();
if (owning_thread_id_ != current_id) {
- LOG4CXX_ERROR(g_logger, "Single-threaded object owned by thread "
+ LOG4CXX_ERROR(logger_, "Single-threaded object owned by thread "
<< owning_thread_id_
<< " is accessed from thread "
<< current_id << "\n"