diff options
Diffstat (limited to 'src/components/include')
22 files changed, 208 insertions, 332 deletions
diff --git a/src/components/include/protocol/common.h b/src/components/include/protocol/common.h index 53d7dd9cb7..f9fdd08fae 100644 --- a/src/components/include/protocol/common.h +++ b/src/components/include/protocol/common.h @@ -216,7 +216,7 @@ enum RESULT_CODE { RESULT_REASSIGN = 12, RESULT_XML_PARSING = 13, RESULT_RESEND_ACK = 14, - RESULT_DEFERRED = 15, + RESULT_DEFRERRED = 15, RESULT_ENCRYPTION_FAILED = 16, RESULT_HEARTBEAT_IS_NOT_SUPPORTED = 17, RESULT_UNKNOWN = 255 diff --git a/src/components/include/protocol/service_type.h b/src/components/include/protocol/service_type.h index b5870e0af1..ab049be9b7 100644 --- a/src/components/include/protocol/service_type.h +++ b/src/components/include/protocol/service_type.h @@ -61,6 +61,7 @@ const uint8_t SERVICE_TYPE_NAVI = 0x0B; */ const uint8_t SERVICE_TYPE_BULK = 0x0F; + /** * \brief Enum describing possible types of sessions: RPC for API messages, Navi for video streaming, bulk for PutFile. @@ -82,4 +83,5 @@ ServiceType ServiceTypeFromByte(uint8_t type); uint8_t ServiceTypeToByte(ServiceType type); } // namespace protocol_handler + #endif // SRC_COMPONENTS_INCLUDE_PROTOCOL_SERVICE_TYPE_H_ diff --git a/src/components/include/protocol_handler/session_observer.h b/src/components/include/protocol_handler/session_observer.h index 2418887267..9a958f6fa7 100644 --- a/src/components/include/protocol_handler/session_observer.h +++ b/src/components/include/protocol_handler/session_observer.h @@ -96,12 +96,6 @@ class SessionObserver { const protocol_handler::ServiceType &service_type) = 0; /** - * \brief Callback function used by ProtocolHandler - * when Mobile Application start message flood - * \param connection_key used by other components as application identifier - */ - virtual void OnApplicationFloodCallBack(const uint32_t &connection_key) = 0; - /** * \brief Creates unique identifier of session (can be used as hash) * from given connection identifier * within which session exists and session number. @@ -163,7 +157,6 @@ class SessionObserver { transport_manager::ConnectionUID connection_handle, uint8_t session_id) = 0; - #ifdef ENABLE_SECURITY /** * \brief Sets crypto context of connection diff --git a/src/components/include/transport_manager/transport_adapter/device.h b/src/components/include/transport_manager/transport_adapter/device.h index e7bca5a46b..78d3b44958 100644 --- a/src/components/include/transport_manager/transport_adapter/device.h +++ b/src/components/include/transport_manager/transport_adapter/device.h @@ -76,8 +76,6 @@ class Device { virtual ApplicationList GetApplicationList() const = 0; - virtual void Stop() { } - inline const DeviceUID& unique_device_id() const { return unique_device_id_; } diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter.h b/src/components/include/transport_manager/transport_adapter/transport_adapter.h index b73333e535..2edf173110 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h @@ -1,4 +1,4 @@ -/* +/** * \file transport_adapter.h * \brief TransportAdapter class header file. * @@ -123,12 +123,6 @@ class TransportAdapter { virtual Error Init() = 0; /** - * @brief Stops device adapter - * Called from transport manager to stop device adapter - */ - virtual void Terminate() = 0; - - /** * @brief Add listener to the container(list) of device adapter listeners. * * @param listener Pointer to the device adapter listener. diff --git a/src/components/include/transport_manager/transport_manager.h b/src/components/include/transport_manager/transport_manager.h index 25745e7485..40790ac0ab 100644 --- a/src/components/include/transport_manager/transport_manager.h +++ b/src/components/include/transport_manager/transport_manager.h @@ -59,12 +59,6 @@ class TransportManager { virtual int Init() = 0; /** - * @brief Reinitializes transport manager - * @return Error code - */ - virtual int Reinit() = 0; - - /** * @brief Start scanning for new devices. * * @return Code error. diff --git a/src/components/include/transport_manager/transport_manager_listener.h b/src/components/include/transport_manager/transport_manager_listener.h index 0684e8f22f..5033a95d17 100644 --- a/src/components/include/transport_manager/transport_manager_listener.h +++ b/src/components/include/transport_manager/transport_manager_listener.h @@ -143,7 +143,7 @@ class TransportManagerListener { /** * @brief Notifies about recieving message from TM. * - * @param message Received message + * @param message Recieved message **/ virtual void OnTMMessageReceived(const ::protocol_handler::RawMessagePtr message) = 0; diff --git a/src/components/include/utils/atomic.h b/src/components/include/utils/atomic.h index f80455b748..bfbcff9dc9 100644 --- a/src/components/include/utils/atomic.h +++ b/src/components/include/utils/atomic.h @@ -28,15 +28,15 @@ * 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_H_ -#define SRC_COMPONENTS_INCLUDE_UTILS_ATOMIC_H_ +*/ #ifdef __QNXNTO__ #include <atomic.h> #endif +#ifndef SRC_COMPONENTS_INCLUDE_UTILS_ATOMIC_H_ +#define SRC_COMPONENTS_INCLUDE_UTILS_ATOMIC_H_ + #if defined(__QNXNTO__) #define atomic_post_inc(ptr) atomic_add_value((ptr), 1) #elif defined(__GNUG__) diff --git a/src/components/include/utils/conditional_variable.h b/src/components/include/utils/conditional_variable.h index f7159ad6fe..58119a0cfd 100644 --- a/src/components/include/utils/conditional_variable.h +++ b/src/components/include/utils/conditional_variable.h @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2013, Ford Motor Company * All rights reserved. * @@ -43,7 +43,6 @@ namespace sync_primitives { class AutoLock; -class Lock; namespace impl { #if defined(OS_POSIX) @@ -82,7 +81,6 @@ class ConditionalVariable { // Wait forever or up to milliseconds time limit void Wait(AutoLock& auto_lock); - void Wait(Lock& lock); WaitStatus WaitFor(AutoLock& auto_lock, int32_t milliseconds); private: impl::PlatformConditionalVariable cond_var_; diff --git a/src/components/include/utils/date_time.h b/src/components/include/utils/date_time.h index c8cef32ef4..766932652d 100644 --- a/src/components/include/utils/date_time.h +++ b/src/components/include/utils/date_time.h @@ -1,34 +1,34 @@ /* - * 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. - */ +* 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_INCLUDE_UTILS_DATE_TIME_H_ #define SRC_COMPONENTS_INCLUDE_UTILS_DATE_TIME_H_ @@ -50,7 +50,6 @@ 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 TimevalStruct getCurrentTime(); @@ -81,6 +80,5 @@ class DateTime { }; } // namespace date_time -bool operator<(const TimevalStruct& time1, const TimevalStruct& time2); -bool 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..910a88052f 100644 --- a/src/components/include/utils/lock.h +++ b/src/components/include/utils/lock.h @@ -34,14 +34,11 @@ #if defined(OS_POSIX) #include <pthread.h> -#include <sched.h> #else #error Please implement lock for your OS #endif #include <stdint.h> #include "utils/macro.h" -#include "utils/atomic.h" -#include "utils/memory_barrier.h" namespace sync_primitives { @@ -51,31 +48,6 @@ typedef pthread_mutex_t PlatformMutex; #endif } // namespace impl - -class SpinMutex { - public: - SpinMutex() - : state_(0) { } - void Lock() { - if (atomic_post_set(&state_) == 0) { - return; - } - for(;;) { - sched_yield(); - if (state_ == 0 && atomic_post_set(&state_) == 0) { - return; - } - } - } - void Unlock() { - state_ = 0; - } - ~SpinMutex() { - } - private: - volatile unsigned int state_; -}; - /* Platform-indepenednt NON-RECURSIVE lock (mutex) wrapper Please use AutoLock to ackquire and (automatically) release it It eases balancing of multple lock taking/releasing and makes it diff --git a/src/components/include/utils/logger.h b/src/components/include/utils/logger.h index 734acc5046..7c00c5d3aa 100644 --- a/src/components/include/utils/logger.h +++ b/src/components/include/utils/logger.h @@ -37,11 +37,11 @@ #include <errno.h> #include <string.h> #include <sstream> + #include <apr_time.h> #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 @@ -57,23 +57,19 @@ #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() + // 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() - 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()); \ + logger::push_log(loggerPtr, logLevel, accumulator.str(), apr_time_now(), LOG4CXX_LOCATION, ::log4cxx::spi::LoggingEvent::getCurrentThreadName()); \ } \ } \ } while (false) @@ -114,8 +110,8 @@ #undef LOG4CXX_TRACE #define LOG4CXX_TRACE(loggerPtr, logEvent) LOG_WITH_LEVEL(loggerPtr, ::log4cxx::Level::getTrace(), logEvent) - #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_TRACE_ENTER(logger) LOG4CXX_TRACE(logger, "ENTER: " << __PRETTY_FUNCTION__ ) + #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) << ")") @@ -177,8 +173,8 @@ #define LOG4CXX_FATAL_EXT(logger, logEvent) #define LOG4CXX_FATAL_STR_EXT(logger, logEvent) - #define LOG4CXX_AUTO_TRACE_WITH_NAME_SPECIFIED(loggerPtr, auto_trace) - #define LOG4CXX_AUTO_TRACE(loggerPtr) + #define LOG4CXX_TRACE_ENTER(logger) + #define LOG4CXX_TRACE_EXIT(logger) #endif // ENABLE_LOG #endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOGGER_H_ diff --git a/src/components/include/utils/logger_status.h b/src/components/include/utils/logger_status.h index 17fa0562c2..e28fa6f839 100644 --- a/src/components/include/utils/logger_status.h +++ b/src/components/include/utils/logger_status.h @@ -45,7 +45,7 @@ typedef enum { // this variable is only changed when creating and deleting logger thread // its reads and writes are believed to be atomic // thus it shall be considered thread safe -extern volatile LoggerStatus logger_status; +extern LoggerStatus logger_status; } // namespace logger diff --git a/src/components/include/utils/macro.h b/src/components/include/utils/macro.h index dc737dbe71..bf34b199b5 100644 --- a/src/components/include/utils/macro.h +++ b/src/components/include/utils/macro.h @@ -32,12 +32,8 @@ #ifndef SRC_COMPONENTS_INCLUDE_UTILS_MACRO_H_ #define SRC_COMPONENTS_INCLUDE_UTILS_MACRO_H_ -#ifdef DEBUG #include <assert.h> -#else // RELEASE #include <stdio.h> -#endif -#include "logger.h" @@ -58,27 +54,14 @@ #define FRIEND_DELETER_DESTRUCTOR(TypeName) \ friend utils::deleters::Deleter<TypeName>::~Deleter() -#ifdef DEBUG - #define ASSERT(condition) \ - 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__) -#endif - #define DCHECK(condition) \ if (!(condition)) { \ - CREATE_LOGGERPTR_LOCAL(logger_, "assert"); \ - LOG4CXX_FATAL(logger_, "DCHECK failed with \"" << #condition \ - << "\" [" << __FUNCTION__ << "][" << __FILE__ << ':' << __LINE__ << ']'); \ - ASSERT((condition)); \ + printf("\nDCHECK [%s:%d][%s]", __FILE__, __LINE__, __FUNCTION__); \ + printf("[Check failed: " #condition "]\n\n"); \ + assert(false); \ } -#define NOTREACHED() DCHECK(!"Unreachable code") +#define NOTREACHED() DCHECK(false) // Allows to perform static check that virtual function from base class is // actually being overriden if compiler support is available diff --git a/src/components/include/utils/memory_barrier.h b/src/components/include/utils/memory_barrier.h index 43c7c9df14..312894e034 100644 --- a/src/components/include/utils/memory_barrier.h +++ b/src/components/include/utils/memory_barrier.h @@ -28,7 +28,7 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ +*/ #ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_MEMORY_BARRIER_H_ #define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_MEMORY_BARRIER_H_ diff --git a/src/components/include/utils/message_queue.h b/src/components/include/utils/message_queue.h index 9ef77374ba..9d998cc698 100644 --- a/src/components/include/utils/message_queue.h +++ b/src/components/include/utils/message_queue.h @@ -28,7 +28,7 @@ * 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 MESSAGE_QUEUE_CLASS #define MESSAGE_QUEUE_CLASS diff --git a/src/components/include/utils/prioritized_queue.h b/src/components/include/utils/prioritized_queue.h index 2a8ebf0a7b..4bec901f59 100644 --- a/src/components/include/utils/prioritized_queue.h +++ b/src/components/include/utils/prioritized_queue.h @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2013, Ford Motor Company * All rights reserved. * diff --git a/src/components/include/utils/shared_ptr.h b/src/components/include/utils/shared_ptr.h index 07f8ad9366..604bee998b 100644 --- a/src/components/include/utils/shared_ptr.h +++ b/src/components/include/utils/shared_ptr.h @@ -164,6 +164,7 @@ class SharedPtr { operator bool() const; void reset(); void reset(ObjectType* other); + void release(); ObjectType* get() const; /** @@ -196,8 +197,6 @@ class SharedPtr { * @brief Pointer to reference counter. **/ uint32_t* mReferenceCounter; - - void release(); }; template<typename ObjectType> diff --git a/src/components/include/utils/threads/message_loop_thread.h b/src/components/include/utils/threads/message_loop_thread.h index c01ebfd067..e051c48904 100644 --- a/src/components/include/utils/threads/message_loop_thread.h +++ b/src/components/include/utils/threads/message_loop_thread.h @@ -39,14 +39,13 @@ #include "utils/logger.h" #include "utils/macro.h" #include "utils/message_queue.h" -#include "utils/threads/thread.h" -#include "utils/shared_ptr.h" +#include "utils/threads/thread_manager.h" +#include "utils/lock.h" namespace threads { -/** - * \class MessageLoopThread - * \brief Handles a thread which sole purpose is to pump messages pushed +/* + * Class that handles a thread which sole purpose is to pump messages pushed * to it's queue. To handle messages someone, Handler must be implemented and * passed to MessageLoopThread constructor. */ @@ -80,10 +79,6 @@ class MessageLoopThread { // Places a message to the therad's queue. Thread-safe. void PostMessage(const Message& message); - - // Process already posted messages and stop thread processing. Thread-safe. - void Shutdown(); - private: /* * Implementation of ThreadDelegate that actually pumps the queue and is @@ -95,20 +90,19 @@ class MessageLoopThread { // threads::ThreadDelegate overrides virtual void threadMain() OVERRIDE; - virtual void exitThreadMain() OVERRIDE; - + virtual bool exitThreadMain() OVERRIDE; private: // Handle all messages that are in the queue until it is empty void DrainQue(); + private: // Handler that processes messages Handler& handler_; // Message queue that is actually owned by MessageLoopThread MessageQueue<Message, Queue>& message_queue_; + sync_primitives::Lock active_lock; }; - private: MessageQueue<Message, Queue> message_queue_; - LoopThreadDelegate* thread_delegate_; threads::Thread* thread_; }; @@ -118,10 +112,8 @@ 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_)) { - const bool started = thread_->start(thread_opts); + : thread_(threads::CreateThread(name.c_str(), new LoopThreadDelegate(&message_queue_, handler))) { + bool started = thread_->startWithOptions(thread_opts); if (!started) { CREATE_LOGGERPTR_LOCAL(logger_, "Utils") LOG4CXX_ERROR(logger_, "Failed to start thread " << name); @@ -130,10 +122,7 @@ MessageLoopThread<Q>::MessageLoopThread(const std::string& name, template<class Q> MessageLoopThread<Q>::~MessageLoopThread() { - Shutdown(); - thread_->join(); - delete thread_delegate_; - threads::DeleteThread(thread_); + thread_->stop(); } template <class Q> @@ -141,11 +130,6 @@ void MessageLoopThread<Q>::PostMessage(const Message& message) { message_queue_.push(message); } -template <class Q> -void MessageLoopThread<Q>::Shutdown() { - thread_->stop(); -} - ////////// template<class Q> MessageLoopThread<Q>::LoopThreadDelegate::LoopThreadDelegate( @@ -158,9 +142,8 @@ MessageLoopThread<Q>::LoopThreadDelegate::LoopThreadDelegate( template<class Q> void MessageLoopThread<Q>::LoopThreadDelegate::threadMain() { - CREATE_LOGGERPTR_LOCAL(logger_, "Utils") - LOG4CXX_AUTO_TRACE(logger_); - while (!message_queue_.IsShuttingDown()) { + sync_primitives::AutoLock auto_lock(active_lock); + while(!message_queue_.IsShuttingDown()){ DrainQue(); message_queue_.wait(); } @@ -169,15 +152,18 @@ void MessageLoopThread<Q>::LoopThreadDelegate::threadMain() { } template<class Q> -void MessageLoopThread<Q>::LoopThreadDelegate::exitThreadMain() { - CREATE_LOGGERPTR_LOCAL(logger_, "Utils") - LOG4CXX_AUTO_TRACE(logger_); +bool MessageLoopThread<Q>::LoopThreadDelegate::exitThreadMain() { message_queue_.Shutdown(); + { + sync_primitives::AutoLock auto_lock(active_lock); + // Prevent canceling thread until queue is drained + } + return true; } template<class Q> void MessageLoopThread<Q>::LoopThreadDelegate::DrainQue() { - while (!message_queue_.empty()) { + while(!message_queue_.empty()) { handler_.Handle(message_queue_.pop()); } } diff --git a/src/components/include/utils/threads/thread.h b/src/components/include/utils/threads/thread.h index 6c3968c51f..3b81cf3454 100644 --- a/src/components/include/utils/threads/thread.h +++ b/src/components/include/utils/threads/thread.h @@ -43,16 +43,16 @@ #include "utils/macro.h" #include "utils/threads/thread_delegate.h" #include "utils/threads/thread_options.h" -#include "utils/conditional_variable.h" -#include "utils/lock.h" namespace threads { +namespace impl { #if defined(OS_POSIX) typedef pthread_t PlatformThreadHandle; #else #error Please implement thread for your OS #endif +} /** * Non platform specific thread abstraction that establishes a @@ -76,69 +76,56 @@ typedef pthread_t PlatformThreadHandle; * printf("ok!\n"); */ class Thread; -void enqueue_to_join(Thread*); - Thread* CreateThread(const char* name, ThreadDelegate* delegate); void DeleteThread(Thread*); class Thread { - private: - const std::string name_; - // Should be locked to protect delegate_ value - sync_primitives::Lock delegate_lock_; - ThreadDelegate* delegate_; - PlatformThreadHandle handle_; - ThreadOptions thread_options_; - // Should be locked to protect isThreadRunning_ and thread_created_ values - sync_primitives::Lock state_lock_; - volatile unsigned int isThreadRunning_; - volatile bool stopped_; - volatile bool finalized_; - bool thread_created_; - // Signalled when Thread::start() is called - sync_primitives::ConditionalVariable run_cond_; + friend Thread* CreateThread(const char*, ThreadDelegate*); + friend void DeleteThread(Thread*); public: /** + * Class that represents unique in-process thread identifier + * due to restriction of pthread API it only allows checks + * for equality to different thread id and no ordering. + * + * ostream<< operator is provided for this class which + * outputs thread name associated to an identifier. + */ + class Id { + public: + explicit Id(const impl::PlatformThreadHandle& id): id_(id) {} + bool operator==(const Id& that) const; + impl::PlatformThreadHandle Handle() const { return id_; } + private: + impl::PlatformThreadHandle id_; + friend class Thread; + }; + + // Get unique ID of currently executing thread + static Id CurrentId(); + + // Get name associated with thread identified by thread_id + static std::string NameFromId(const Id& thread_id); + + // Give thread thread_id a name, helpful for debugging + static void SetNameForId(const Id& thread_id, const std::string& name); + + /** * Starts the thread. * @return true if the thread was successfully started. */ bool start(); + ThreadDelegate* delegate() const; + /** - * Starts the thread. Behaves exactly like \ref start() in addition to + * Starts the thread. Behaves exactly like Start in addition to * allow to override the default options. - * @param options Thread options. Look for 'threads/thread_options.h' + * @param options - thread options. Look for 'threads/thread_options.h' * for details. * @return true if the thread was successfully started. */ - bool start(const ThreadOptions& options); - - void WaitForRun(); - - sync_primitives::Lock& delegate_lock() { - return delegate_lock_; - } - - ThreadDelegate *delegate() const { - return delegate_; - } - - void set_delegate(ThreadDelegate *delegate) { - DCHECK(!isThreadRunning_); - delegate_ = delegate; - } - - friend Thread* CreateThread(const char* name, ThreadDelegate* delegate); - friend void DeleteThread(Thread*); - - public: - - // Get unique ID of currently executing thread - static PlatformThreadHandle CurrentId(); - - // Give thread thread_id a name, helpful for debugging - static void SetNameForId(const PlatformThreadHandle& thread_id, std::string name); - + bool startWithOptions(const ThreadOptions& options); /** * Signals the thread to exit and returns once the thread has exited. @@ -150,14 +137,11 @@ class Thread { */ void stop(); - - void join(); - /** * Get thread name. * @return thread name */ - const std::string& name() { + const std::string& thread_name() { return name_; } @@ -170,7 +154,9 @@ class Thread { return isThreadRunning_; } - void set_running(bool running); + void set_running(bool running) { + isThreadRunning_ = running; + } /** * Is thread joinable? @@ -192,8 +178,16 @@ class Thread { * The native thread handle. * @return thread handle. */ - PlatformThreadHandle thread_handle() const { - return handle_; + impl::PlatformThreadHandle thread_handle() const { + return thread_handle_; + } + + /** + * Thread id. + * @return return thread id. + */ + Id thread_id() const { + return Id(thread_handle()); } /** @@ -210,7 +204,11 @@ class Thread { static size_t kMinStackSize; protected: - sync_primitives::ConditionalVariable state_cond_; + const std::string name_; + ThreadDelegate* delegate_; + impl::PlatformThreadHandle thread_handle_; + ThreadOptions thread_options_; + volatile unsigned int isThreadRunning_; private: /** @@ -218,17 +216,19 @@ class Thread { * @param name - display string to identify the thread. * @param delegate - thread procedure delegate. Look for * 'threads/thread_delegate.h' for details. - * LifeCycle thread , otherwise it will be joined in stop method - * NOTE: delegate will be deleted after thread will be joined + * NOTE: delegate will be deleted by destructor. * This constructor made private to prevent * Thread object to be created on stack */ Thread(const char* name, ThreadDelegate* delegate); + DISALLOW_COPY_AND_ASSIGN(Thread); - virtual ~Thread(); - static void* threadFunc(void* arg); - static void cleanup(void* arg); + virtual ~Thread() { } }; +inline bool operator!= (const Thread::Id& left, const Thread::Id& right) { + return !(left == right); +} +std::ostream& operator<<(std::ostream& os, const Thread::Id& thread_id); } // namespace threads #endif // SRC_COMPONENTS_INCLUDE_UTILS_THREADS_THREAD_H_ diff --git a/src/components/include/utils/threads/thread_delegate.h b/src/components/include/utils/threads/thread_delegate.h index 1d9be175fc..47e68f1e83 100644 --- a/src/components/include/utils/threads/thread_delegate.h +++ b/src/components/include/utils/threads/thread_delegate.h @@ -35,65 +35,30 @@ #include <pthread.h> -#include "utils/lock.h" - namespace threads { -enum ThreadState { - kInit = 0, - kStarted = 1, - kStopReq = 2 -}; - -class Thread; - /** * Thread procedure interface. * Look for "threads/thread.h" for example */ class ThreadDelegate { - public: - ThreadDelegate() - : state_(kInit), - thread_(NULL) { } - /** - * \brief Thread procedure. - */ - virtual void threadMain() = 0; + public: - /** - * Should be called to free all resources allocated in threadMain - * and exiting threadMain - * This function should be blocking and return only when threadMain() will be - * finished in other case segmantation failes are possible - */ - virtual void exitThreadMain(); + /** + * Thread procedure. + */ + virtual void threadMain() = 0; - virtual ~ThreadDelegate(); - - Thread* thread() const { - return thread_; - } - - void set_thread(Thread *thread); - - bool ImproveState(unsigned int to) { - state_lock_.Lock(); - if ((state_ + 1 == to) || - (to == kInit && state_ == kStopReq)) { - state_ = to; + /** + * Should be called to free all resources allocated in threadMain + * and exiting threadMain + * This function should be blocking and return only when threadMain() will be + * finished in other case segmantation failes are possible + */ + virtual bool exitThreadMain() { + return false; } - state_lock_.Unlock(); - return state_ == to; - } - - unsigned int state() const { - return state_; - } - private: - volatile unsigned int state_; - sync_primitives::SpinMutex state_lock_; - Thread* thread_; + virtual ~ThreadDelegate() { } }; } // namespace threads diff --git a/src/components/include/utils/timer_thread.h b/src/components/include/utils/timer_thread.h index 70fbd36458..a3481e4b4b 100644 --- a/src/components/include/utils/timer_thread.h +++ b/src/components/include/utils/timer_thread.h @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2013, Ford Motor Company * All rights reserved. * @@ -28,7 +28,7 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */ +*/ #ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_TIMER_THREAD #define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_TIMER_THREAD @@ -52,9 +52,8 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "Utils") class TimerDelegate; -/** - * \class TimerThread - * \brief TimerThread class provide possibility to run timer in a separate thread. +/* + * The TimerThread class provide possibility to run timer in a separate thread. * The client should specify callee and const callback function. * Example usage: * @@ -111,17 +110,12 @@ class TimerThread { virtual void stop(); /** - * @brief Tell timer status + * @brief Tell tmer status * @return true if timer is currently running, otherwise return false */ virtual bool isRunning(); - /** - * @brief method suspends timer execution - */ - virtual void pause(); - - /** + /* * @brief Stop timer update timeout and start timer again * Note that it cancel thread of timer, If you use it from callback, * it probably will stop execution of callback function @@ -129,6 +123,7 @@ class TimerThread { * */ virtual void updateTimeOut(const uint32_t timeout_seconds); + threads::Thread* thread_; protected: /** @@ -164,7 +159,7 @@ class TimerThread { /** * @brief Called by thread::thread to free all allocated resources. */ - virtual void exitThreadMain(); + virtual bool exitThreadMain(); /** * @brief Set new Timeout @@ -207,12 +202,13 @@ class TimerThread { private: DISALLOW_COPY_AND_ASSIGN(TimerLooperDelegate); }; - threads::Thread* thread_; void (T::*callback_)(); T* callee_; TimerDelegate* delegate_; + //threads::Thread* thread_; std::string name_; - volatile bool is_looper_; + mutable bool is_running_; + bool is_looper_; DISALLOW_COPY_AND_ASSIGN(TimerThread); }; @@ -223,55 +219,53 @@ TimerThread<T>::TimerThread(const char* name, T* callee, void (T::*f)(), bool is callback_(f), callee_(callee), delegate_(NULL), - name_(name), + is_running_(false), 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_); + LOG4CXX_INFO(logger_, "TimerThread is to destroy " << name_); + stop(); callback_ = NULL; callee_ = NULL; } template <class T> void TimerThread<T>::start(uint32_t timeout_seconds) { - LOG4CXX_AUTO_TRACE(logger_); - if (isRunning()) { + LOG4CXX_TRACE(logger_, "Starting timer " << this); + if (is_running_) { LOG4CXX_INFO(logger_, "TimerThread start needs stop " << name_); stop(); } - updateTimeOut(timeout_seconds); - thread_->start(); + + delegate_ = is_looper_ ? + new TimerLooperDelegate(this) : + new TimerDelegate(this); + delegate_->setTimeOut(timeout_seconds); + + thread_ = threads::CreateThread("TimerThread", delegate_); + if (delegate_ && thread_) { + is_running_ = true; + thread_->start(); + } } template <class T> void TimerThread<T>::stop() { - LOG4CXX_AUTO_TRACE(logger_); - DCHECK(thread_); - LOG4CXX_DEBUG(logger_, "Stopping timer " << name_); - thread_->join(); + LOG4CXX_TRACE(logger_, "Stopping timer " << this); + if (is_running_ && delegate_ && thread_) { + LOG4CXX_INFO(logger_, "TimerThread thread_ stop " << name_); + thread_->stop(); + is_running_ = false; + } else { + LOG4CXX_INFO(logger_, "TimerThread thread_ not stop " << name_); + } } template <class T> bool TimerThread<T>::isRunning() { - DCHECK(thread_); - return thread_->is_running(); -} - -template <class T> -void TimerThread<T>::pause() { - LOG4CXX_DEBUG(logger_, "Suspension of timer " << name_); - const uint32_t wait_seconds = std::numeric_limits<uint32_t>::max(); - updateTimeOut(wait_seconds); + return is_running_; } template <class T> @@ -279,9 +273,15 @@ void TimerThread<T>::updateTimeOut(const uint32_t timeout_seconds) { delegate_->setTimeOut(timeout_seconds); } -template <class T>void TimerThread<T>::onTimeOut() const { +template <class T> +void TimerThread<T>::onTimeOut() const { if (callee_ && callback_) { (callee_->*callback_)(); + /* + if (!is_looper_) { + stop(); + } + */ } } @@ -308,7 +308,6 @@ 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(); @@ -317,21 +316,19 @@ void TimerThread<T>::TimerDelegate::threadMain() { // 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(); - return; - } else { - LOG4CXX_DEBUG(logger_, "Timeout reset force: " << TimerDelegate::timeout_seconds_); - return; + break; } } + if (!stop_flag_) { + timer_thread_->onTimeOut(); + timer_thread_->stop(); + } } 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 = @@ -339,7 +336,7 @@ void TimerThread<T>::TimerLooperDelegate::threadMain() { // 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"); + LOG4CXX_TRACE(logger_, "Timer timeout " << wait_milliseconds_left); TimerDelegate::timer_thread_->onTimeOut(); } else { LOG4CXX_DEBUG(logger_, "Timeout reset force: " << TimerDelegate::timeout_seconds_); @@ -349,10 +346,11 @@ void TimerThread<T>::TimerLooperDelegate::threadMain() { template <class T> -void TimerThread<T>::TimerDelegate::exitThreadMain() { +bool TimerThread<T>::TimerDelegate::exitThreadMain() { sync_primitives::AutoLock auto_lock(state_lock_); stop_flag_ = true; termination_condition_.NotifyOne(); + return true; } template <class T> @@ -371,9 +369,9 @@ int32_t TimerThread<T>::TimerThread::TimerDelegate::calculateMillisecondsLeft() 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; + const int32_t millisecconds_in_second = 1000; + if (wait_seconds_left < std::numeric_limits<int32_t>::max() / millisecconds_in_second) { + wait_milliseconds_left = millisecconds_in_second * wait_seconds_left; } return wait_milliseconds_left; } |