summaryrefslogtreecommitdiff
path: root/SDL_Core/src/components/Utils
diff options
context:
space:
mode:
authorJustin Dickow <jjdickow@gmail.com>2014-03-18 13:46:46 -0400
committerJustin Dickow <jjdickow@gmail.com>2014-03-18 13:46:46 -0400
commitba492fb83c258bc60ca68120ce964a95b41133b5 (patch)
treeaf99c087941d65a19831397c1ec5eb34850cfc7f /SDL_Core/src/components/Utils
parent8504605b01177da2e55bee6abe4c3f20c82da379 (diff)
downloadsmartdevicelink-ba492fb83c258bc60ca68120ce964a95b41133b5.tar.gz
initial commit for API 3.0 (replaced all)
Diffstat (limited to 'SDL_Core/src/components/Utils')
-rw-r--r--SDL_Core/src/components/Utils/CMakeLists.txt28
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/MessageQueue.h164
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/MultithreadingMap.h43
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/WorkWithOS.h25
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/back_trace.h75
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/bitstream.h170
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/conditional_variable.h94
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/date_time.h56
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/dict.h225
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/file_system.h207
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/lock.h132
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/logger.h72
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/macro.h77
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/memory_barrier.h54
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/message_queue.h181
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/prioritized_queue.h89
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/shared_ptr.h342
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/signals.h44
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/singleton.h179
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/stl_utils.h81
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/threads/message_loop_thread.h136
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/threads/thread.h237
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/threads/thread_delegate.h71
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/threads/thread_manager.h117
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/threads/thread_options.h107
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/threads/thread_validator.h105
-rw-r--r--SDL_Core/src/components/Utils/include/Utils/timer_thread.h336
-rw-r--r--SDL_Core/src/components/Utils/include/utils/atomic.h69
-rw-r--r--SDL_Core/src/components/Utils/src/WorkWithOS.cpp147
-rw-r--r--SDL_Core/src/components/Utils/src/back_trace.cc107
-rw-r--r--SDL_Core/src/components/Utils/src/bitstream.cc129
-rw-r--r--SDL_Core/src/components/Utils/src/conditional_variable_posix.cc134
-rw-r--r--SDL_Core/src/components/Utils/src/date_time.cc74
-rw-r--r--SDL_Core/src/components/Utils/src/file_system.cc404
-rw-r--r--SDL_Core/src/components/Utils/src/lock_posix.cc126
-rw-r--r--SDL_Core/src/components/Utils/src/signals_linux.cc57
-rw-r--r--SDL_Core/src/components/Utils/src/threads/posix_thread.cc185
-rw-r--r--SDL_Core/src/components/Utils/src/threads/thread_manager.cc120
-rw-r--r--SDL_Core/src/components/Utils/src/threads/thread_validator.cc95
39 files changed, 4711 insertions, 383 deletions
diff --git a/SDL_Core/src/components/Utils/CMakeLists.txt b/SDL_Core/src/components/Utils/CMakeLists.txt
index dca9f3d2d..e456a51ff 100644
--- a/SDL_Core/src/components/Utils/CMakeLists.txt
+++ b/SDL_Core/src/components/Utils/CMakeLists.txt
@@ -1,12 +1,32 @@
include_directories (
./include
- ../../thirdPartyLibs/logger/include/
- ../../thirdPartyLibs/logger/log4cplus-1.1.0/include/
- ${CMAKE_BINARY_DIR}/src/thirdPartyLibs/logger/log4cplus-1.1.0/include
+ ../config_profile/include
+ ../media_manager/include/
+ ../protocol_handler/include/
)
set (SOURCES
- ./src/WorkWithOS.cpp
+ ./src/bitstream.cc
+ ./src/conditional_variable_posix.cc
+ ./src/file_system.cc
+ ./src/threads/posix_thread.cc
+ ./src/threads/thread_manager.cc
+ ./src/threads/thread_validator.cc
+ ./src/lock_posix.cc
+ ./src/date_time.cc
+ ./src/signals_linux.cc
)
+if (BUILD_BACKTRACE_SUPPORT)
+ list(APPEND SOURCES
+ ./src/back_trace.cc
+ )
+endif()
+
add_library("Utils" ${SOURCES})
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "QNX")
+ target_link_libraries ("Utils" log4cxx apr-1 aprutil-1)
+else()
+ target_link_libraries ("Utils" log4cxx apr-1 aprutil-1 rt)
+endif()
diff --git a/SDL_Core/src/components/Utils/include/Utils/MessageQueue.h b/SDL_Core/src/components/Utils/include/Utils/MessageQueue.h
deleted file mode 100644
index 3adb03e7f..000000000
--- a/SDL_Core/src/components/Utils/include/Utils/MessageQueue.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
-* \file MessageQueue.hpp
-* \brief Template MessageQueue class header.
-*/
-
-
-#ifndef MESSAGE_QUEUE_CLASS
-#define MESSAGE_QUEUE_CLASS
-
-
-#include <pthread.h>
-#include <queue>
-
-/**
- * \class MessageQueue
- * \brief Wrapper for multithreading queue.
-*/
-template <typename T> class MessageQueue
-{
-public:
- /**
- * \brief Default constructor
- */
- MessageQueue();
-
- /**
- * \brief Constructor
- * \param queue Existing queue.
- */
- explicit MessageQueue( std::queue<T> queue );
-
- /**
- * \brief Destructor
- */
- ~MessageQueue();
-
- /**
- * \brief Returns size of the queue.
- * \return Size of the queue.
- */
- int size() const;
-
- /**
- * \brief If queue is empty.
- * \return Is queue empty.
- */
- bool empty() 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();
-
-private:
- /**
- *\brief Queue
- */
- std::queue<T> mQueue;
- /**
- *\brief Mutex for queue locking.
- */
- mutable pthread_mutex_t mMutex;
- /**
- *\brief Condition for waiting.
- */
- pthread_cond_t mCond;
- /**
- *\brief Bool condition for waiting.
- */
- bool mIsUp;
-};
-
-template <typename T> MessageQueue<T>::MessageQueue()
-:mMutex( PTHREAD_MUTEX_INITIALIZER )
-,mCond( PTHREAD_COND_INITIALIZER )
-,mIsUp( false )
-{
- pthread_mutex_init( &mMutex, NULL );
- pthread_cond_init( &mCond, NULL );
-}
-
-template <typename T> MessageQueue<T>::MessageQueue( std::queue<T> queue )
-{
- pthread_mutex_init( &mMutex, NULL );
- pthread_cond_init( &mCond, NULL );
- pthread_mutex_lock( &mMutex );
- mQueue = std::queue<T>( queue );
- pthread_mutex_unlock( &mMutex );
-}
-
-template <typename T> MessageQueue<T>::~MessageQueue()
-{
- pthread_cond_destroy( &mCond );
- pthread_mutex_destroy( &mMutex );
-}
-
-template<typename T> void MessageQueue<T>::wait()
-{
- pthread_mutex_lock( &mMutex );
- while ( !mIsUp )
- {
- pthread_cond_wait( &mCond, &mMutex );
- }
- mIsUp = false;
- pthread_mutex_unlock( &mMutex );
-}
-
-template <typename T> int MessageQueue<T>::size() const
-{
- int result = 0;
- pthread_mutex_lock( &mMutex );
- result = mQueue.size();
- pthread_mutex_unlock( &mMutex );
- return result;
-}
-
-template <typename T> bool MessageQueue<T>::empty() const
-{
- bool result = true;
- pthread_mutex_lock( &mMutex );
- result = mQueue.empty();
- pthread_mutex_unlock( &mMutex );
- return result;
-}
-
-template <typename T> void MessageQueue<T>::push( const T & element )
-{
- pthread_mutex_lock( &mMutex );
- mQueue.push( element );
-
- pthread_cond_signal( &mCond );
- mIsUp = true;
-
- pthread_mutex_unlock( &mMutex );
-}
-
-template <typename T> T MessageQueue<T>::pop( )
-{
- pthread_mutex_lock( &mMutex );
- if ( mQueue.empty() )
- {
- //error, TRACE
- }
-
- T result = mQueue.front();
- mQueue.pop();
-
- pthread_mutex_unlock( &mMutex );
- return result;
-}
-
-#endif // MESSAGE_QUEUE_CLASS
diff --git a/SDL_Core/src/components/Utils/include/Utils/MultithreadingMap.h b/SDL_Core/src/components/Utils/include/Utils/MultithreadingMap.h
deleted file mode 100644
index 5a0f76a66..000000000
--- a/SDL_Core/src/components/Utils/include/Utils/MultithreadingMap.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef MULTITHREADED_MAP_CLASS
-#define MULTITHREADED_MAP_CLASS
-
-#include <map>
-
-template <typename T, typename K> class MultithreadingMap
-{
-public:
- MultithreadingMap();
- ~MultithreadingMap();
-
- int size() const;
-
- bool empty() const;
-
- void insert( const std::pair<const T,K> & element );
-
- K & find( const T & key );
-
-private:
- std::multimap<T,K> mMap;
-
- /**
- *\brief Mutex for queue locking.
- */
- mutable pthread_mutex_t mMutex;
-
-};
-
-template <typename T, typename K> MultithreadingMap<T,K>::MultithreadingMap() :
-mMutex( PTHREAD_MUTEX_INITIALIZER )
-{
- pthread_mutex_init( &mMutex, NULL );
-}
-
-template <typename T, typename K> MultithreadingMap<T,K>::~MultithreadingMap()
-{
- pthread_mutex_destroy( &mMutex );
-}
-
-
-
-#endif // MULTITHREADED_MAP_CLASS \ No newline at end of file
diff --git a/SDL_Core/src/components/Utils/include/Utils/WorkWithOS.h b/SDL_Core/src/components/Utils/include/Utils/WorkWithOS.h
deleted file mode 100644
index 2fbb58576..000000000
--- a/SDL_Core/src/components/Utils/include/Utils/WorkWithOS.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
-* \file WorkWithOS.h
-* \brief class source file.
-*/
-
-#ifndef WORKWITHSYSTEM_INCLUDE
-#define WORKWITHSYSTEM_INCLUDE
-
-#include <string.h>
-#include <vector>
-
-namespace WorkWithOS
-{
- unsigned long int getAvailableSpace();
- std::string createDirectory(const std::string & directoryName);
- bool checkIfDirectoryExists(const std::string & directoryName);
- bool checkIfFileExists(const std::string & fileName);
- bool createFileAndWrite(const std::string & fileName, const std::vector<unsigned char>& fileData);
- std::string getFullPath(const std::string & fileName);
- bool deleteFile(const std::string & fileName);
- std::vector<std::string> listFilesInDirectory(const std::string & directoryName);
- bool readFileAsBinary(const std::string& fileName, std::vector<unsigned char>& v);
-}
-
-#endif // WORKWITHSYSTEM_INCLUDE
diff --git a/SDL_Core/src/components/Utils/include/Utils/back_trace.h b/SDL_Core/src/components/Utils/include/Utils/back_trace.h
new file mode 100644
index 000000000..7f8912faf
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/back_trace.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_BACK_TRACE_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_BACK_TRACE_H_
+
+#include <ostream>
+#include <vector>
+#include <string>
+#include "utils/threads/thread.h"
+
+namespace utils {
+
+/*
+ * Class that captures stack trace in place where it was created.
+ * Can be stored and passed for further processing
+ * ostream output operator is available for these objects so stacktrace
+ * here and now can be easily printed as
+ *
+ * std::cout<<utils::Backtrace()<<std::endl;
+ */
+class Backtrace {
+ public:
+ // Inspect stack up to 128 calls back
+ static const int32_t kDefaultDepth = 128;
+ static const int32_t kSkipTop = 0;
+ /* Capture backtrace and store. Limit captured stack length to
+ * count symbols and remove first skip_top elements from it
+ * (to avoid polluting stack trace with debugging function names)
+ */
+ Backtrace(int32_t count = kDefaultDepth, int32_t skip_top = kSkipTop);
+ ~Backtrace();
+
+ // Captured symbols in order from topmost stack frame to last captured
+ std::vector<std::string> CallStack() const;
+ threads::Thread::Id ThreadId() const;
+
+ private:
+ threads::Thread::Id thread_id_;
+ std::vector<void*> backtrace_;
+};
+
+std::ostream& operator<< (std::ostream& os, const Backtrace& bt);
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_BACK_TRACE_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/bitstream.h b/SDL_Core/src/components/Utils/include/Utils/bitstream.h
new file mode 100644
index 000000000..cba15abd8
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/bitstream.h
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_BITSTREAM_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_BITSTREAM_H_
+
+#include "stdint.h"
+
+#include <climits>
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include "utils/macro.h"
+
+namespace utils {
+
+// Big endian input bitstream class
+// Tool to read and parse incoming data in a recursive way
+// Has sublte similarity to standard stream classes in a way
+// it handles stream parsing errors:
+// If error while parsing stream occurs, whole stream is marked as
+// "bad" and all subsequent parsing is stopped.
+class BitStream {
+ public:
+ BitStream(uint8_t* bytes, size_t bytes_count);
+ ~BitStream();
+
+ // Mark stream as badly-formed.
+ // Should be called by Extract* family of procedures if they decide
+ // that stream is invalid
+ void MarkBad() { bad_ = true; }
+ // Predicates to check whether there were errors while parsing
+ // Stream is good when it is created
+ bool IsGood() { return !bad_; }
+ bool IsBad() { return bad_; }
+ operator bool() { return IsGood(); }
+ private:
+ // These two functions are used for internal stream checks only
+ // Stream parser procedures must not define their logic depending on
+ // amount of data left in particular bit stream
+
+ // Amount of full bytes left in stream
+ size_t FullBytesLeft();
+ // Amount of total bits left in stream
+ size_t BitsLeft();
+
+ // These stream extractors are helpers for direct friend extractors
+ // of this class.
+
+ // Extract single value, amount of bits read from stream depends on T size
+ // If there is not enough data in the stream, stream is marked bad
+ template<typename T>
+ void Extract(T& val);
+
+ // Read single value, amount of bits read from stream is signaled by |bits|
+ // parameter. T must be wide enough to hold this amount of bits.
+ // If there is not enough data in the stream, stream is marked bad
+ template<typename T>
+ void ExtractBits(T& val, size_t bits);
+
+ // Extract |length| bytes from the stream. Stream read position
+ // must be byte aligned when it is called, stream is marked bad otherwise.
+ // If there is not enough data in the stream, it is marked bad.
+ void ExtractBytes(void* buffer, size_t length);
+
+ private:
+ const uint8_t* bytes_;
+ const size_t bytes_count_;
+ size_t byte_offset_;
+ size_t bit_offset_;
+ bool bad_;
+ private:
+ friend void Extract(BitStream*, uint8_t*);
+ friend void Extract(BitStream*, uint8_t*, size_t);
+ friend void Extract(BitStream*, uint32_t*);
+ friend void Extract(BitStream*, uint32_t*, size_t);
+ friend void Extract(BitStream*, std::string*, size_t);
+ friend void Extract(BitStream*, std::vector<uint8_t>*, size_t);
+
+};
+
+// Extract single byte from stream
+// If there is not enough data in the stream it is marked bad.
+void Extract(BitStream* bs, uint8_t* val);
+
+// Extract defined amount of |bits| from stream and store them
+// in a byte size |val|. Hence |bits| must be less than 8.
+void Extract(BitStream* bs, uint8_t* val, size_t bits);
+
+// Extract 32 bit word from stream.
+// If there is not enough data in the stream it is marked bad.
+void Extract(BitStream* bs, uint32_t* val);
+
+// Extract up to 32 |bits| from stream and store them in a |val|
+// If there is not enough data in the stream it is marked bad.
+void Extract(BitStream* bs, uint32_t* val, size_t bits);
+
+// Extract |length| bytes from stream and store them to the
+// string |str|. If stream is too short it is marked bad.
+// String must not contain zero bytes.
+void Extract(BitStream* bs, std::string* str, size_t length);
+
+// Extract |length| bytes from stream and store them to the
+// vector |data|. If stream is too short it is marked bad.
+void Extract(BitStream* bs, std::vector<uint8_t>* data, size_t length);
+
+
+// Template member definitions
+template<typename T>
+void BitStream::Extract(T& val) {
+ // Slow but simple implementation
+ // It's a space for bit stream reading optimization
+ ExtractBits(val, sizeof(val) * CHAR_BIT);
+}
+
+template<typename T>
+void BitStream::ExtractBits(T& val, size_t bits) {
+ DCHECK(sizeof(val) * CHAR_BIT >= bits);
+ if (IsGood()) {
+ if (bits > BitsLeft()) {
+ MarkBad();
+ return;
+ }
+ val = T(); // Clear value
+ for (size_t i = 0; i < bits; ++i) {
+ size_t next_bit_number = CHAR_BIT - 1 - bit_offset_;
+ uint8_t nextbit = (bytes_[byte_offset_] >> next_bit_number) & 1;
+ val = (val << 1) | nextbit;
+ ++bit_offset_;
+ if (bit_offset_ == CHAR_BIT) {
+ ++byte_offset_;
+ bit_offset_ = 0;
+ }
+ }
+ }
+}
+
+} // namespace utils
+
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_BITSTREAM_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/conditional_variable.h b/SDL_Core/src/components/Utils/include/Utils/conditional_variable.h
new file mode 100644
index 000000000..433f8d7c0
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/conditional_variable.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_CONDITIONAL_VARIABLE_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_CONDITIONAL_VARIABLE_H_
+
+#if defined(OS_POSIX)
+#include <pthread.h>
+#else
+#error Please implement conditional variable for your OS
+#endif
+#include <stdint.h>
+
+#include "utils/macro.h"
+
+namespace sync_primitives {
+class AutoLock;
+
+namespace impl {
+#if defined(OS_POSIX)
+typedef pthread_cond_t PlatformConditionalVariable;
+#endif
+} // namespace impl
+
+/*
+ * Conditional variable wrapper
+ * Conditional variable is a thing that can be waited on
+ * Wait is finished when other thread puts that thing in a signaled state
+ * (or when timeout is over).
+ * Data that is conditionally accessed should be protected by
+ * a Lock and that lock must be taken before starting to Wait.
+ * When wait is performed, Lock is temporarly released.
+ * When wait is finished, Lock is captured back.
+ * WARNING: Beware of Spurious wakeups
+ * http://en.wikipedia.org/wiki/Spurious_wakeup
+ * Thread can wake up from wait spuriously, without conditional
+ * variable being actually set by other thread. This means
+ * additional check should be made right after thread awakening
+ * and if check fails thread should continue waiting.
+ *
+ * while(!DataReady()) cond_var.Wait(auto_lock);
+ *
+ */
+class ConditionalVariable {
+ public:
+ enum WaitStatus { kNoTimeout, kTimeout };
+ ConditionalVariable();
+ ~ConditionalVariable();
+ // Wakes up single thread that is waiting on this conditional variable
+ void NotifyOne();
+ // Wakes up all waiting threads
+ void Broadcast();
+
+ // Wait forever or up to milliseconds time limit
+ void Wait(AutoLock& auto_lock);
+ WaitStatus WaitFor(AutoLock& auto_lock, int32_t milliseconds );
+ private:
+ impl::PlatformConditionalVariable cond_var_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConditionalVariable);
+};
+
+} // namespace sync_primitives
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_CONDITIONAL_VARIABLE_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/date_time.h b/SDL_Core/src/components/Utils/include/Utils/date_time.h
new file mode 100644
index 000000000..df2d067ac
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/date_time.h
@@ -0,0 +1,56 @@
+/**
+* \file request_watchdog.h
+* \brief DateTime class header file.
+*
+* Copyright (c) 2013, 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_UTILS_DATE_TIME_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_DATE_TIME_H_
+
+#if defined(OS_POSIX)
+#include <sys/time.h>
+typedef struct timeval TimevalStruct;
+#endif
+
+namespace date_time {
+
+class DateTime {
+ public:
+ static const int32_t MILLISECONDS_IN_SECOND = 1000;
+ static const int32_t MICROSECONDS_IN_MILLISECONDS = 1000;
+
+ static TimevalStruct getCurrentTime();
+ static int32_t calculateTimeSpan(TimevalStruct sinceTime);
+};
+
+} // namespace date_time
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_DATE_TIME_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/dict.h b/SDL_Core/src/components/Utils/include/Utils/dict.h
new file mode 100644
index 000000000..bb60390d1
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/dict.h
@@ -0,0 +1,225 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_H_
+
+#include <map>
+
+namespace utils {
+
+template<typename Key, typename Record>
+class Dictionary {
+ private:
+ typedef std::map<Key, Record> ItemContainer;
+ typedef std::map<Key, Dictionary> SubitemContainer;
+
+ public:
+/**
+ * @brief Typedef for subitems iterator
+ */
+ typedef typename SubitemContainer::iterator iterator;
+/**
+ * @brief Typedef for subitems const iterator
+ */
+ typedef typename SubitemContainer::const_iterator const_iterator;
+
+/**
+ * @brief Typedef for items iterator
+ */
+ typedef typename ItemContainer::iterator rec_iterator;
+/**
+ * @brief Typedef for items const iterator
+ */
+ typedef typename ItemContainer::const_iterator rec_const_iterator;
+
+/**
+ * @brief add an item to the dictionary
+ * @param key - item key
+ * @param record - item value
+ */
+ void AddItem(const Key& key, const Record& record);
+/**
+ * @brief add a subitem to the dictionary
+ * @param key - subitem key
+ * @param subitem - subitem dictionary
+ */
+ void AddSubitem(const Key& key, const Dictionary& subitem);
+/**
+ * @brief item under specified key
+ * @param key - item key
+ * @return item with specified key of default-constructed item
+ */
+ Record& ItemAt(const Key& key);
+/**
+ * @brief item under specified key
+ * @param key - item key
+ * @return item with specified key of default-constructed item
+ */
+ const Record& ItemAt(const Key& key) const;
+/**
+ * @brief subitem under specified key
+ * @param key - subitem key
+ * @return subitem with specified key of default-constructed dictionary
+ */
+ Dictionary& SubitemAt(const Key& key);
+/**
+ * @brief subitem under specified key
+ * @param key - subitem key
+ * @return subitem with specified key of default-constructed dictionary
+ */
+ const Dictionary& SubitemAt(const Key& key) const;
+/**
+ * @brief first subitem
+ * @return iterator pointing to the first subitem
+ */
+ iterator begin();
+
+/**
+ * @brief first subitem
+ * @return const iterator pointing to the first subitem
+ */
+ const_iterator begin() const;
+
+/**
+ * @brief first item
+ * @return iterator pointing to the first item
+ */
+ rec_iterator rec_begin();
+
+/**
+ * @brief first item
+ * @return iterator pointing to the first item
+ */
+ rec_const_iterator rec_begin() const;
+
+/**
+ * @brief end of subitem list
+ * @return iterator pointing to the end of subitem list
+ */
+ iterator end();
+/**
+ * @brief end of subitem list
+ * @return const iterator pointing to the end of subitem list
+ */
+ const_iterator end() const;
+
+ /**
+ * @brief end of item list
+ * @return iterator pointing to the end of item list
+ */
+ rec_iterator rec_end();
+
+ /**
+ * @brief end of item list
+ * @return const iterator pointing to the end of item list
+ */
+ rec_const_iterator rec_end() const;
+
+private:
+ ItemContainer items_;
+ SubitemContainer subitems_;
+};
+
+template<typename Key, typename Record>
+void Dictionary<Key, Record>::AddItem(const Key& key, const Record& record) {
+ items_.insert(std::make_pair(key, record));
+}
+
+template<typename Key, typename Record>
+void Dictionary<Key, Record>::AddSubitem(const Key& key, const Dictionary& subitem) {
+ subitems_.insert(std::make_pair(key, subitem));
+}
+
+template<typename Key, typename Record>
+Record& Dictionary<Key, Record>::ItemAt(const Key& key) {
+ return items_.at(key);
+}
+
+template<typename Key, typename Record>
+const Record& Dictionary<Key, Record>::ItemAt(const Key& key) const {
+ return items_.at(key);
+}
+
+template<typename Key, typename Record>
+Dictionary<Key, Record>& Dictionary<Key, Record>::SubitemAt(const Key& key) {
+ return subitems_.at(key);
+}
+
+template<typename Key, typename Record>
+const Dictionary<Key, Record>& Dictionary<Key, Record>::SubitemAt(const Key& key) const {
+ return subitems_.at(key);
+}
+
+template<typename Key, typename Record>
+typename Dictionary<Key, Record>::iterator Dictionary<Key, Record>::begin() {
+ return subitems_.begin();
+}
+
+template<typename Key, typename Record>
+typename Dictionary<Key, Record>::const_iterator Dictionary<Key, Record>::begin() const {
+ return subitems_.begin();
+}
+
+template<typename Key, typename Record>
+typename Dictionary<Key, Record>::rec_iterator Dictionary<Key, Record>::rec_begin() {
+ return items_.begin();
+}
+
+template<typename Key, typename Record>
+typename Dictionary<Key, Record>::rec_const_iterator Dictionary<Key, Record>::rec_begin() const {
+ return items_.begin();
+}
+
+template<typename Key, typename Record>
+typename Dictionary<Key, Record>::iterator Dictionary<Key, Record>::end() {
+ return subitems_.end();
+}
+
+template<typename Key, typename Record>
+typename Dictionary<Key, Record>::const_iterator Dictionary<Key, Record>::end() const {
+ return subitems_.end();
+}
+
+template<typename Key, typename Record>
+typename Dictionary<Key, Record>::rec_iterator Dictionary<Key, Record>::rec_end() {
+ return items_.end();
+}
+
+template<typename Key, typename Record>
+typename Dictionary<Key, Record>::rec_const_iterator Dictionary<Key, Record>::rec_end() const {
+ return items_.end();
+}
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/file_system.h b/SDL_Core/src/components/Utils/include/Utils/file_system.h
new file mode 100644
index 000000000..c40c15f39
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/file_system.h
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_FILE_SYSTEM_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_FILE_SYSTEM_H_
+
+#include <string.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include "utils/logger.h"
+
+namespace file_system {
+
+
+/**
+ * @brief Get available disc space.
+ *
+ * @return free disc space.
+ */
+uint64_t GetAvailableDiskSpace();
+
+/*
+ * @brief Get size of current directory
+ *
+ * @param path to directory
+ */
+uint32_t DirectorySize(const std::string& path);
+
+/*
+ * @brief Get size of current file
+ *
+ * @param path to file
+ * @return size of file, return 0 if file not exist
+ */
+uint32_t FileSize(const std::string& path);
+
+
+/**
+ * @brief Get available app space
+ * @param name of app
+ * @return free app space.
+ */
+uint32_t GetAvailableSpaceForApp(const std::string& name);
+
+/**
+ * @brief Creates directory
+ * @param name path to directory
+ * @return path to created directory.
+ */
+std::string CreateDirectory(const std::string& name);
+
+/**
+ * @brief Checks the file to see whether the file is a directory
+ * @param name path to file
+ * @return returns true if file is directory.
+ */
+bool IsDirectory(const std::string& name);
+
+/**
+ * @brief Is directory exist
+ * @param name path to directory
+ * @return returns true if directory is exists.
+ */
+bool DirectoryExists(const std::string& name);
+
+/**
+ * @brief Is file exist
+ * @param name path to file
+ * @return returns true if file is exists.
+ */
+bool FileExists(const std::string& name);
+
+/**
+ * @brief Writes to file
+ *
+ * @remark - create file if it doesn't exist
+ * @param name path to file
+ * @param data data to write
+ * @return returns true if the operation is successfully.
+ */
+bool Write(const std::string& file_name,
+ const std::vector<uint8_t>& data,
+ std::ios_base::openmode mode = std::ios_base::out);
+
+/**
+ * @brief Opens file stream for writing
+ * @param file_name path to file to write data to
+ * @return returns pointer to opened stream in case of success;
+ * otherwise returns NULL
+ */
+std::ofstream* Open(const std::string& file_name,
+ std::ios_base::openmode mode = std::ios_base::out);
+
+/**
+ * @brief Writes to file stream
+ * @param file_stream file stream to be written to
+ * @param data data to be written to file
+ * @param data_size size of data to be written to file
+ * @return returns true if the operation is successfully.
+ */
+bool Write(std::ofstream* const file_stream,
+ const uint8_t* data,
+ uint32_t data_size);
+
+/**
+ * @brief Closes file stream
+ * @param file_stream file stream to be closed
+ */
+void Close(std::ofstream* file_stream);
+
+/**
+ * @brief Returns full file path
+ *
+ * @param name file name
+ * @return returns full file path.
+ */
+std::string FullPath(const std::string& name);
+
+/**
+ * @brief Removes file
+ *
+ * @param name path to file
+ * @return returns true if the file is successfully deleted.
+ */
+bool DeleteFile(const std::string& name);
+
+/**
+ * @brief Removes directory.
+ *
+ * @param name path to directory.
+ * @param is_recursively true if you need delete directory recursively, otherwise false.
+ * @return returns true if the directory is successfully deleted.
+ */
+bool RemoveDirectory(const std::string& directory_name,
+ bool is_recursively = true);
+
+/**
+ * @brief Check access rights
+ *
+ * @param name path to file.
+ * @param how Read/write attribute.
+ * @return returns true if file has the given mode.
+ */
+bool IsAccessible(const std::string& name, int32_t how);
+
+/**
+ * @brief Lists all files in given directory
+ *
+ * @param name path to directory.
+ * @return returns list of files.
+ */
+std::vector<std::string> ListFiles(const std::string& directory_name);
+
+/**
+ * @brief Reads from file
+ *
+ * @param name path to file
+ * @param result read data
+ * @return returns true if the operation is successfully.
+ */
+bool ReadBinaryFile(const std::string& name,
+ std::vector<uint8_t>& result);
+
+bool ReadFile(const std::string& name, std::string& result);
+
+/**
+ * @brief Convert special symbols in system path to percent-encoded
+ *
+ * @param name path to file
+ * @return returns converted path.
+*/
+const std::string ConvertPathForURL(const std::string& path);
+
+} // namespace file_system
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_FILE_SYSTEM_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/lock.h b/SDL_Core/src/components/Utils/include/Utils/lock.h
new file mode 100644
index 000000000..2aaddbbc6
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/lock.h
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_LOCK_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOCK_H_
+
+#if defined(OS_POSIX)
+#include <pthread.h>
+#else
+#error Please implement lock for your OS
+#endif
+
+#include "utils/macro.h"
+
+namespace sync_primitives {
+
+namespace impl {
+#if defined(OS_POSIX)
+typedef pthread_mutex_t PlatformMutex;
+#endif
+} // namespace impl
+
+/* 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
+ Impossible to forget to release the lock:
+ ...
+ ConcurentlyAccessedData data_;
+ sync_primitives::Lock data_lock_;
+ ...
+ {
+ sync_primitives::AutoLock auto_lock(data_lock_);
+ data_.ReadOrWriteData();
+ } // lock is automatically released here
+*/
+class Lock {
+ public:
+ Lock();
+ ~Lock();
+
+ // Ackquire the lock. Must be called only once on a thread.
+ // Please consider using AutoLock to capture it.
+ void Ackquire();
+ // Release the lock. Must be called only once on a thread after lock.
+ // was acquired. Please consider using AutoLock to automatically release
+ // the lock
+ void Release();
+ // Try if lock can be captured and lock it if it was possible.
+ // If it captured, lock must be manually released calling to Release
+ // when protected resource access was finished.
+ // @returns wether lock was captured.
+ bool Try();
+
+ private:
+ impl::PlatformMutex mutex_;
+
+#ifndef NDEBUG
+ // Basic debugging aid, a flag that signals wether this lock is currently taken
+ // Allows detection of abandoned and recursively captured mutexes
+ bool lock_taken_;
+ void AssertFreeAndMarkTaken();
+ void AssertTakenAndMarkFree();
+#else
+ void AssertFreeAndMarkTaken() {}
+ void AssertTakenAndMarkFree() {}
+#endif
+
+ private:
+ friend class ConditionalVariable;
+ DISALLOW_COPY_AND_ASSIGN(Lock);
+};
+
+// This class is used to automatically acquire and release the a lock
+class AutoLock {
+ public:
+ explicit AutoLock(Lock& lock)
+ : lock_(lock) { lock_.Ackquire(); }
+ ~AutoLock() { lock_.Release(); }
+ private:
+ Lock& GetLock(){ return lock_; }
+ Lock& lock_;
+
+ private:
+ friend class AutoUnlock;
+ friend class ConditionalVariable;
+ DISALLOW_COPY_AND_ASSIGN(AutoLock);
+};
+
+// This class is used to temporarly unlock autolocked lock
+class AutoUnlock {
+ public:
+ explicit AutoUnlock(AutoLock& lock)
+ : lock_(lock.GetLock()) { lock_.Release(); }
+ ~AutoUnlock() { lock_.Ackquire(); }
+ private:
+ Lock& lock_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AutoUnlock);
+};
+
+} // sync_primitives
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOCK_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/logger.h b/SDL_Core/src/components/Utils/include/Utils/logger.h
new file mode 100644
index 000000000..a88c6aa16
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/logger.h
@@ -0,0 +1,72 @@
+/**
+ * \file LOG4CXXLogger.hpp
+ * \brief Definitions required by logger.
+ * Stores device information
+ *
+ * Copyright (c) 2013, 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 LOG4CXXLOGGER_HPP_
+ #include <errno.h>
+ #include <string.h>
+ #include <log4cxx/logger.h>
+ #include <log4cxx/propertyconfigurator.h>
+
+namespace log4cxx
+{
+ #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)
+
+ #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 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 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)
+
+ #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)
+
+ #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) << ")")
+}
+
+#define LOG4CXXLOGGER_HPP_
+
+
+#endif /* LOG4CXXLOGGER_HPP_ */
diff --git a/SDL_Core/src/components/Utils/include/Utils/macro.h b/SDL_Core/src/components/Utils/include/Utils/macro.h
new file mode 100644
index 000000000..738f5f4eb
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/macro.h
@@ -0,0 +1,77 @@
+//
+// Copyright (c) 2013, 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_UTILS_MACRO_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_MACRO_H_
+
+#include <assert.h>
+#include <stdio.h>
+
+// 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) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+
+// A macro to allow utils::Singleton call derivative constructor and destructor
+#define FRIEND_BASE_SINGLETON_CLASS(TypeName) \
+ friend class utils::Singleton<TypeName>
+
+// A macro to allow utils::deleters::Deleter::~Deleter() call class destructor
+#define FRIEND_DELETER_DESTRUCTOR(TypeName) \
+ friend utils::deleters::Deleter<TypeName>::~Deleter()
+
+#define DCHECK(condition) \
+ if (!(condition)) { \
+ printf("\nDCHECK [%s:%d][%s]", __FILE__, __LINE__, __FUNCTION__); \
+ printf("[Check failed: " #condition); \
+ printf("]\n\n"); \
+ assert(false); \
+ }
+
+#define NOTREACHED() DCHECK(false)
+
+// Allows to perform static check that virtual function from base class is
+// actually being overriden if compiler support is available
+#if __cplusplus >= 201103L
+#define OVERRIDE override
+#else
+#define OVERRIDE
+#endif
+
+/*
+* @brief Calculate size of na array
+* @param arr array, which size need to calculate
+*/
+#define ARRAYSIZE(arr) sizeof (arr) / sizeof(*arr)
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_MACRO_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/memory_barrier.h b/SDL_Core/src/components/Utils/include/Utils/memory_barrier.h
new file mode 100644
index 000000000..9ac935a21
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/memory_barrier.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_MEMORY_BARRIER_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_MEMORY_BARRIER_H_
+
+#ifdef __QNXNTO__
+#include <sys/cpuinline.h>
+#endif
+
+namespace utils {
+
+inline void memory_barrier() {
+#if defined(__QNXNTO__)
+ __cpu_membarrier();
+#elif defined(__GNUG__)
+ __sync_synchronize();
+#else
+#warning "memory_barrier() implementation does nothing"
+#endif
+}
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_MEMORY_BARRIER_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/message_queue.h b/SDL_Core/src/components/Utils/include/Utils/message_queue.h
new file mode 100644
index 000000000..e043440d6
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/message_queue.h
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2013, 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 MESSAGE_QUEUE_CLASS
+#define MESSAGE_QUEUE_CLASS
+
+#include <queue>
+
+#include "utils/conditional_variable.h"
+#include "utils/lock.h"
+#include "utils/logger.h"
+#include "utils/prioritized_queue.h"
+
+/**
+ * \class MessageQueue
+ * \brief Wrapper for multithreading queue.
+ */
+
+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.
+ */
+ int32_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();
+ private:
+
+ /**
+ *\brief Queue
+ */
+ Queue queue_;
+ volatile bool shutting_down_;
+ /**
+ *\brief Platform specific syncronisation variable
+ */
+ mutable sync_primitives::Lock queue_lock_;
+ mutable 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() {
+ if (!queue_.empty()) {
+ log4cxx::LoggerPtr logger =
+ log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
+ LOG4CXX_ERROR(logger, "Destruction of non-drained queue");
+ }
+}
+
+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> int32_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 {
+ sync_primitives::AutoLock auto_lock(queue_lock_);
+ return queue_.empty();
+}
+
+template<typename T, class Q> bool MessageQueue<T, Q>::IsShuttingDown() const {
+ sync_primitives::AutoLock auto_lock(queue_lock_);
+ return shutting_down_;
+}
+
+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"
+ " that is being shut down");
+ }
+ queue_.push(element);
+ queue_new_items_.Broadcast();
+}
+
+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");
+ }
+ T result = queue_.front();
+ queue_.pop();
+ return result;
+}
+
+template<typename T, class Q> void MessageQueue<T, Q>::Shutdown() {
+ sync_primitives::AutoLock auto_lock(queue_lock_);
+ shutting_down_ = true;
+ queue_new_items_.Broadcast();
+}
+
+#endif // MESSAGE_QUEUE_CLASS
diff --git a/SDL_Core/src/components/Utils/include/Utils/prioritized_queue.h b/SDL_Core/src/components/Utils/include/Utils/prioritized_queue.h
new file mode 100644
index 000000000..0023c2bdb
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/prioritized_queue.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_PRIORITIZED_QUEUE_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_PRIORITIZED_QUEUE_H_
+
+#include <queue>
+#include <map>
+#include <iostream>
+
+#include "utils/macro.h"
+
+namespace utils {
+
+/*
+ * Template queue class that gives out messages respecting their priority
+ * Message class must have size_t PriorityOrder() method implemented
+ */
+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) {
+ }
+ // All api mimics usual std queue interface
+ void push(const value_type& message) {
+ size_t message_priority = message.PriorityOrder();
+ queues_[message_priority].push(message);
+ ++total_size_;
+ }
+ size_t size() const {
+ return total_size_;
+ }
+ bool empty() const {
+ return queues_.empty();
+ }
+ value_type front() {
+ DCHECK(!queues_.empty() && !queues_.rbegin()->second.empty());
+ return queues_.rbegin()->second.front();
+ }
+ void pop() {
+ DCHECK(!queues_.empty() && !queues_.rbegin()->second.empty());
+ typename QueuesMap::iterator last = --queues_.end();
+ last->second.pop();
+ --total_size_;
+ if (last->second.empty()) {
+ queues_.erase(last);
+ }
+ }
+ private:
+ QueuesMap queues_;
+ size_t total_size_;
+};
+
+}
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_
diff --git a/SDL_Core/src/components/Utils/include/Utils/shared_ptr.h b/SDL_Core/src/components/Utils/include/Utils/shared_ptr.h
new file mode 100644
index 000000000..0e06d62c6
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/shared_ptr.h
@@ -0,0 +1,342 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_SHARED_PTR_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SHARED_PTR_H_
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "macro.h"
+#include "atomic.h"
+
+namespace utils {
+/**
+ * @brief Shared pointer.
+ *
+ * Pointer to an object with reference counting.
+ * Object will be automatically deallocated when last shared
+ * pointer is destroyed.
+ *
+ * @tparam ObjectType Type of wrapped object.
+ **/
+template<typename ObjectType>
+class SharedPtr {
+ public:
+ /**
+ * @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(void);
+
+ /**
+ * @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);
+
+ /**
+ * @brief Member access operator.
+ *
+ * @return Wrapped object.
+ **/
+ ObjectType* operator->(void) 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(void);
+
+ /**
+ * @brief Wrapped object.
+ **/
+ ObjectType* mObject;
+
+ /**
+ * @brief Pointer to reference counter.
+ **/
+ uint32_t* mReferenceCounter;
+};
+
+template<typename ObjectType>
+inline utils::SharedPtr<ObjectType>::SharedPtr(ObjectType* Object)
+ : mObject(NULL),
+ mReferenceCounter(new uint32_t(1)) {
+ DCHECK(Object != NULL);
+ mObject = Object;
+}
+
+template<typename ObjectType>
+inline utils::SharedPtr<ObjectType>::SharedPtr()
+ : mObject(0),
+ mReferenceCounter(0) {
+}
+
+template<typename ObjectType>
+inline utils::SharedPtr<ObjectType>::SharedPtr(
+ const SharedPtr<ObjectType>& Other)
+ : mObject(0),
+ mReferenceCounter(0) {
+ *this = Other;
+}
+
+template<typename ObjectType>
+template<typename OtherObjectType>
+inline utils::SharedPtr<ObjectType>::SharedPtr(
+ const SharedPtr<OtherObjectType>& Other)
+ : mObject(0),
+ mReferenceCounter(0) {
+ *this = Other;
+}
+
+template<typename ObjectType>
+inline utils::SharedPtr<ObjectType>::~SharedPtr(void) {
+ dropReference();
+}
+
+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 {
+ return (mObject == Other.mObject);
+}
+
+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) {
+ dropReference();
+
+ mObject = Other.mObject;
+ mReferenceCounter = Other.mReferenceCounter;
+
+ if (0 != mReferenceCounter) {
+ atomic_post_inc(mReferenceCounter);
+ }
+
+ return *this;
+}
+
+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;
+
+ if (0 != casted_pointer.mReferenceCounter) {
+ atomic_post_inc(casted_pointer.mReferenceCounter);
+ }
+
+ return casted_pointer;
+}
+
+template<typename ObjectType> ObjectType*
+utils::SharedPtr<ObjectType>::operator->(void) const {
+ return mObject;
+}
+
+template<typename ObjectType> ObjectType&
+utils::SharedPtr<ObjectType>::operator*() const {
+ DCHECK(mObject);
+ return *mObject;
+}
+
+template<typename ObjectType>
+utils::SharedPtr<ObjectType>::operator bool() const {
+ return 0 != mObject;
+}
+
+template<typename ObjectType> void
+utils::SharedPtr<ObjectType>::reset() {
+ reset_impl(0);
+}
+
+template<typename ObjectType> void
+utils::SharedPtr<ObjectType>::reset(ObjectType* other) {
+ DCHECK(other != NULL);
+ reset_impl(other);
+}
+
+template<typename ObjectType> void
+utils::SharedPtr<ObjectType>::reset_impl(ObjectType* other) {
+ dropReference();
+ mObject = other;
+ mReferenceCounter = new uint32_t(1);
+}
+
+template<typename ObjectType>
+inline void SharedPtr<ObjectType>::dropReference(void) {
+ if (0 != mReferenceCounter) {
+ if (1 == atomic_post_dec(mReferenceCounter)) {
+
+ delete mObject;
+ mObject = 0;
+
+ delete mReferenceCounter;
+ mReferenceCounter = 0;
+ }
+ }
+}
+
+template<typename ObjectType>
+ObjectType* SharedPtr<ObjectType>::get() const {
+ return mObject;
+}
+
+template<typename ObjectType>
+inline bool SharedPtr<ObjectType>::valid() const {
+ return (mObject != NULL);
+}
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SHARED_PTR_H_
+
+// vim: set ts=2 sw=2 et:
diff --git a/SDL_Core/src/components/Utils/include/Utils/signals.h b/SDL_Core/src/components/Utils/include/Utils/signals.h
new file mode 100644
index 000000000..ad2a2d183
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/signals.h
@@ -0,0 +1,44 @@
+/**
+* \file signals.h
+* \brief Signal (i.e. SIGINT) handling.
+* Copyright (c) 2013, 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_UTILS_SIGNALS_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SIGNALS_H_
+
+namespace utils {
+bool SubscribeToTerminateSignal(void (*func)(int32_t p));
+bool ResetSubscribeToTerminateSignal();
+void ForwardSignal();
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SIGNALS_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/singleton.h b/SDL_Core/src/components/Utils/include/Utils/singleton.h
new file mode 100644
index 000000000..35ad50393
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/singleton.h
@@ -0,0 +1,179 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_SINGLETON_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SINGLETON_H_
+
+#include "lock.h"
+#include "memory_barrier.h"
+#include "atomic.h"
+
+namespace utils {
+
+namespace deleters {
+
+class DummyDeleter {
+ public:
+ void grab(void* pointer) {
+ }
+};
+
+template<typename T>
+class Deleter {
+ public:
+ Deleter() : pointer_(0) {
+ }
+ ~Deleter() {
+ if (pointer_) {
+ delete pointer_;
+ }
+ }
+ void grab(T* pointer) {
+ pointer_ = pointer;
+ }
+ private:
+ T* pointer_;
+};
+
+} // namespace deleters
+
+template<typename T, class Deleter = deleters::DummyDeleter>
+class Singleton {
+/**
+ * @brief Singleton template
+ * Singleton classes must derive from this template specialized with class itself:
+ *
+ * class MySingleton : public Singleton<MySingleton> {...};
+ *
+ * All such classes must declare instance() method as friend
+ * by adding FRIEND_BASE_SINGLETON_CLASS macro from macro.h to class definition:
+ *
+ * FRIEND_BASE_SINGLETON_CLASS(MySingleton);
+ *
+ * Instance of this class (if created) can be deleted by Deleter destructor
+ * which is called after main() (or from exit())
+ * This requires T destructor to be accessible for Deleter (e.g. public)
+ * Deleter template parameter can be specified with any class
+ * with public default constructor, destructor and method
+ * void grab(T*);
+ * However, default Deleter specification does nothing
+ *
+ * Also instance can be deleted explicitly by calling destroy() method
+ *
+ * Both instance() and destroy() methods are thread safe
+ * but not thread safety between simultaneous calls
+ * of instance() and destroy() is cared about
+ */
+ public:
+/**
+ * @brief Returns the singleton of class
+ */
+ static T* instance();
+/**
+ * @brief Destroys the singleton (if it had been created)
+ */
+ static void destroy();
+/**
+ * @brief Checks whether the singleton exists
+ */
+ static bool exists();
+
+ private:
+
+ static T** instance_pointer();
+ static Deleter* deleter();
+};
+
+template<typename T, class Deleter>
+T* Singleton<T, Deleter>::instance() {
+ static sync_primitives::Lock lock;
+
+ T* local_instance;
+ atomic_pointer_assign(local_instance, *instance_pointer());
+ memory_barrier();
+
+ if (!local_instance) {
+ lock.Ackquire();
+ local_instance = *instance_pointer();
+ if (!local_instance) {
+ local_instance = new T();
+ memory_barrier();
+ atomic_pointer_assign(*instance_pointer(), local_instance);
+ deleter()->grab(local_instance);
+ }
+ lock.Release();
+ }
+
+ return local_instance;
+}
+
+template<typename T, class Deleter>
+void Singleton<T, Deleter>::destroy() {
+ static sync_primitives::Lock lock;
+
+ T* local_instance;
+ atomic_pointer_assign(local_instance, *instance_pointer());
+ memory_barrier();
+
+ if (local_instance) {
+ lock.Ackquire();
+ local_instance = *instance_pointer();
+ if (local_instance) {
+ atomic_pointer_assign(*instance_pointer(), 0);
+ memory_barrier();
+ delete local_instance;
+ deleter()->grab(0);
+ }
+ lock.Release();
+ }
+}
+
+template<typename T, class Deleter>
+bool Singleton<T, Deleter>::exists() {
+ return *instance_pointer() != 0;
+}
+
+template<typename T, class Deleter>
+T** Singleton<T, Deleter>::instance_pointer() {
+ static T* instance = 0;
+ return &instance;
+}
+
+template<typename T, class Deleter>
+Deleter* Singleton<T, Deleter>::deleter() {
+ static Deleter deleter;
+ return &deleter;
+}
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SINGLETON_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/stl_utils.h b/SDL_Core/src/components/Utils/include/Utils/stl_utils.h
new file mode 100644
index 000000000..f525c6429
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/stl_utils.h
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_STL_UTILS_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_STL_UTILS_H_
+
+#include "utils/macro.h"
+
+namespace utils {
+
+/*
+ * Utility class that automatically deletes STL collection of
+ * freestore objects
+ */
+template<class T>
+class StlCollectionDeleter {
+ public:
+ typedef T Collection;
+ StlCollectionDeleter(T* collection): collection_(collection) {
+ DCHECK(collection_);
+ }
+ ~StlCollectionDeleter() {
+ for (typename Collection::iterator i = collection_->begin(),
+ end = collection_->end();
+ i != end; ++i) {
+ delete *i;
+ }
+ }
+ private:
+ Collection* collection_;
+};
+
+template<class T>
+class StlMapDeleter {
+ public:
+ typedef T Collection;
+ StlMapDeleter(T* collection): collection_(collection) {
+ DCHECK(collection_);
+ }
+ ~StlMapDeleter() {
+ for (typename Collection::iterator i = collection_->begin(),
+ end = collection_->end();
+ i != end; ++i) {
+ delete i->second;
+ }
+ }
+ private:
+ Collection* collection_;
+};
+
+} // namespace utils
+
+#endif /* SRC_COMPONENTS_UTILS_INCLUDE_UTILS_STL_UTILS_H_ */
diff --git a/SDL_Core/src/components/Utils/include/Utils/threads/message_loop_thread.h b/SDL_Core/src/components/Utils/include/Utils/threads/message_loop_thread.h
new file mode 100644
index 000000000..b2ff91f7b
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/threads/message_loop_thread.h
@@ -0,0 +1,136 @@
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_MESSAGE_LOOP_THREAD_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_MESSAGE_LOOP_THREAD_H_
+
+#include <string>
+#include <queue>
+
+#include "utils/logger.h"
+#include "utils/macro.h"
+#include "utils/message_queue.h"
+#include "utils/threads/thread.h"
+
+namespace threads {
+
+/*
+ * 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.
+ */
+template < class Q >
+class MessageLoopThread {
+ public:
+ typedef Q Queue;
+ typedef typename Queue::value_type Message;
+ /*
+ * Handler interface. It is called from a thread that is
+ * owned by MessageLoopThread so make sure is only accesses
+ * thread-safe data
+ */
+ struct Handler {
+ /*
+ * 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;
+ };
+
+ /*
+ * Constructs new MessageLoopThread. Must be named to aid debugging.
+ */
+ MessageLoopThread(const std::string& name,
+ Handler* handler,
+ const ThreadOptions& thread_opts = ThreadOptions());
+ ~MessageLoopThread();
+
+ // Places a message to the therad's queue. Thread-safe.
+ void PostMessage(const Message& message);
+ private:
+
+ /*
+ * Implementation of ThreadDelegate that actually pumps the queue and is
+ * able to correctly shut it down
+ */
+ struct LoopThreadDelegate : public threads::ThreadDelegate {
+ LoopThreadDelegate(MessageQueue<Message, Queue>* message_queue,
+ Handler* handler);
+
+ // threads::ThreadDelegate overrides
+ virtual void threadMain() 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_;
+ };
+ private:
+ MessageQueue<Message, Queue> message_queue_;
+ threads::Thread thread_;
+};
+
+///////// Implementation
+
+template<class Q>
+MessageLoopThread<Q>::MessageLoopThread(const std::string& name,
+ Handler* handler,
+ const ThreadOptions& thread_opts)
+ : 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);
+ }
+}
+
+template<class Q>
+MessageLoopThread<Q>::~MessageLoopThread() {
+ // this will join us with the thread while it drains message queue
+ thread_.stop();
+}
+
+template <class Q>
+void MessageLoopThread<Q>::PostMessage(const Message& message) {
+ message_queue_.push(message);
+}
+
+//////////
+template<class Q>
+MessageLoopThread<Q>::LoopThreadDelegate::LoopThreadDelegate(
+ MessageQueue<Message, Queue>* message_queue, Handler* handler)
+ : handler_(*handler),
+ message_queue_(*message_queue) {
+ DCHECK(handler != NULL);
+ DCHECK(message_queue != NULL);
+}
+
+template<class Q>
+void MessageLoopThread<Q>::LoopThreadDelegate::threadMain() {
+ while(!message_queue_.IsShuttingDown()){
+ DrainQue();
+ message_queue_.wait();
+ }
+ // Process leftover messages
+ DrainQue();
+}
+
+template<class Q>
+bool MessageLoopThread<Q>::LoopThreadDelegate::exitThreadMain() {
+ message_queue_.Shutdown();
+ // Prevent canceling thread until queue is drained
+ return true;
+}
+
+template<class Q>
+void MessageLoopThread<Q>::LoopThreadDelegate::DrainQue() {
+ while(!message_queue_.empty()) {
+ handler_.Handle(message_queue_.pop());
+ }
+}
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_MESSAGE_LOOP_THREAD_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/threads/thread.h b/SDL_Core/src/components/Utils/include/Utils/threads/thread.h
new file mode 100644
index 000000000..bbe0acde3
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/threads/thread.h
@@ -0,0 +1,237 @@
+/**
+ * \file thread.h
+ * \brief
+ *
+ * Copyright (c) 2013, 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_UTILS_THREADS_THREAD_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_THREAD_H_
+
+#if defined(OS_POSIX)
+#include <pthread.h>
+#endif
+
+#include <ostream>
+#include <string>
+
+#include "utils/macro.h"
+#include "utils/logger.h"
+#include "utils/threads/thread_delegate.h"
+#include "utils/threads/thread_options.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
+ * threads::ThreadDelegate on a new thread.
+ *
+ * ThreadDelegate example:
+ * class TestThread : public threads::ThreadDelegate {
+ * public:
+ * void threadMain() {
+ * printf("Hello, thread!\n");
+ * sleep(2);
+ * }
+ * };
+ *
+ * Example usage:
+ * threads::Thread thread("test thread", new TestThread());
+ * thread.startWithOptions(
+ * threads::ThreadOptions(threads::Thread::kMinStackSize));
+ * printf("join!\n");
+ * thread.join();
+ * printf("ok!\n");
+ */
+class 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;
+ 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(Id thread_id);
+
+ // Give thread thread_id a name, helpful for debugging
+ static void SetNameForId(Id thread_id, const std::string& name);
+
+ /**
+ * Ctor.
+ * @param name - display string to identify the thread.
+ * @param delegate - thread procedure delegate. Look for
+ * 'threads/thread_delegate.h' for details.
+ * NOTE: delegate will be deleted by destructor.
+ */
+ Thread(const char* name, ThreadDelegate* delegate);
+
+ /**
+ * Dtor.
+ */
+ virtual ~Thread();
+
+ /**
+ * Starts the thread.
+ * @return true if the thread was successfully started.
+ */
+ bool start();
+
+ /**
+ * 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'
+ * for details.
+ * @return true if the thread was successfully started.
+ */
+ bool startWithOptions(const ThreadOptions& options);
+
+ /**
+ * Signals the thread to exit and returns once the thread has exited.
+ * After this method returns, the Thread object is completely reset and may
+ * be used as if it were newly constructed (i.e., Start may be called again).
+ *
+ * Stop may be called multiple times and is simply ignored if the thread is
+ * already stopped.
+ */
+ void stop();
+
+ /**
+ * Joins with a thread created via the Create function.
+ * This function blocks the caller until the designated thread exits.
+ * This will invalidate |thread_handle|.
+ */
+ void join();
+
+ /**
+ * Get thread name.
+ * @return thread name
+ */
+ const std::string &thread_name() {
+ return name_;
+ }
+
+ /**
+ * Returns true if the thread has been started, and not yet stopped.
+ * When a thread is running, the thread_id_ is non-zero.
+ * @return true if the thread has been started, and not yet stopped.
+ */
+ bool is_running() const {
+ return isThreadRunning_;
+ }
+
+ /**
+ * Is thread joinable?
+ * @return - Returns true if the thread is joinable.
+ */
+ bool is_joinable() const {
+ return thread_options_.is_joinable();
+ }
+
+ /**
+ * Thread stack size
+ * @return thread stack size
+ */
+ size_t stack_size() const {
+ return thread_options_.stack_size();
+ }
+
+ /**
+ * The native thread handle.
+ * @return thread handle.
+ */
+ impl::PlatformThreadHandle thread_handle() const {
+ return thread_handle_;
+ }
+
+ /**
+ * Thread id.
+ * @return return thread id.
+ */
+ Id thread_id() const {
+ return Id(thread_handle());
+ }
+
+ /**
+ * Thread options.
+ * @return thread options.
+ */
+ const ThreadOptions& thread_options() const {
+ return thread_options_;
+ }
+
+ /**
+ * Minimum size of thread stack for specific platform.
+ */
+ static size_t kMinStackSize;
+
+ protected:
+ std::string name_;
+ ThreadDelegate* delegate_;
+ impl::PlatformThreadHandle thread_handle_;
+ ThreadOptions thread_options_;
+ bool isThreadRunning_;
+
+ static log4cxx::LoggerPtr logger_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Thread);
+};
+
+inline bool operator!= (Thread::Id left, Thread::Id right) {return !(left == right); }
+std::ostream& operator<<(std::ostream& os, Thread::Id thread_id);
+
+} // namespace threads
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_THREAD_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/threads/thread_delegate.h b/SDL_Core/src/components/Utils/include/Utils/threads/thread_delegate.h
new file mode 100644
index 000000000..963eb3bf8
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/threads/thread_delegate.h
@@ -0,0 +1,71 @@
+/**
+ * \file thread_delegate.h
+ * \brief
+ *
+ * Copyright (c) 2013, 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_UTILS_THREADS_THREAD_DELEGATE_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_THREAD_DELEGATE_H_
+
+#include <pthread.h>
+
+namespace threads {
+
+/**
+ * Thread procedure interface.
+ * Look for "threads/thread.h" for example
+ */
+class ThreadDelegate {
+ public:
+ /**
+ * Dtor.
+ */
+ virtual ~ThreadDelegate() {
+ }
+
+ /**
+ * Thread procedure.
+ */
+ virtual void threadMain() = 0;
+
+ /**
+ * Should be called to free all resources allocated in threadMain
+ * and exiting threadMain
+ */
+ virtual bool exitThreadMain() {
+ return false;
+ }
+};
+
+} // namespace threads
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_THREAD_DELEGATE_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/threads/thread_manager.h b/SDL_Core/src/components/Utils/include/Utils/threads/thread_manager.h
new file mode 100644
index 000000000..03330170e
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/threads/thread_manager.h
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_THREADS_THREAD_MANAGER_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_THREAD_MANAGER_H_
+
+#include "utils/threads/thread.h"
+#include "utils/lock.h"
+
+#include <map>
+#include <string>
+#include <set>
+
+#include "utils/macro.h"
+#include "utils/singleton.h"
+
+namespace threads {
+namespace impl {
+
+/*
+ * Generates short and unique names for unnamed threads
+ * and remembers association between thread handle and that short name
+ */
+class UnnamedThreadRegistry {
+ public:
+ UnnamedThreadRegistry();
+ ~UnnamedThreadRegistry();
+ /*
+ * Returns a name for given unnamed thread id.
+ * If id is first seen, new name is generated and memorized
+ * If id is already known, previously generated name is returned
+ */
+ std::string GetUniqueName(PlatformThreadHandle id);
+ private:
+ typedef std::map<PlatformThreadHandle, std::string> IdNameMap;
+ IdNameMap id_number_;
+ int32_t last_thread_number_;
+ sync_primitives::Lock state_lock_;
+};
+
+/*
+ * This class is here currently to remember names associated to threads.
+ * It manages raw impl::PlatformHandles because Thread::Id's do not provide
+ * comparison operator. Current linux implementation relies on fact that
+ * pthread_t is just an integer and every thread has single unique value
+ * associated with it.
+ * OS provides it's own facilities to name threads but
+ */
+class ThreadManager : public utils::Singleton<ThreadManager> {
+ public:
+ // Name a thread. Should be called only once for every thread.
+ // Threads can't be renamed
+ void RegisterName(PlatformThreadHandle id, const std::string& name);
+
+ // Get a name for previously registered thread
+ std::string GetName(PlatformThreadHandle id) const;
+
+ // Forget a name of (possibly destroyed) thread
+ // Make sure to call it after thread is finished
+ // Because thread id's can be recycled
+ void Unregister(PlatformThreadHandle id);
+ private:
+ ThreadManager();
+ ~ThreadManager();
+
+ private:
+ typedef std::set<std::string> NamesSet;
+ typedef std::map<PlatformThreadHandle, std::string> IdNamesMap;
+ // Set of thread names for fast checking if name is unique
+ NamesSet names_;
+ // Map from system handle to the thread name
+ IdNamesMap id_names_;
+ mutable sync_primitives::Lock state_lock_;
+
+ // Generator of shorter sequental names for unnamed threads
+ // Has to memorize every generated name this is why it is mutable
+ mutable UnnamedThreadRegistry unnamed_thread_namer_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ThreadManager);
+
+ FRIEND_BASE_SINGLETON_CLASS(ThreadManager);
+};
+
+} // namespace impl
+} // namespace threads
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_THREAD_MANAGER_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/threads/thread_options.h b/SDL_Core/src/components/Utils/include/Utils/threads/thread_options.h
new file mode 100644
index 000000000..bdeaa367f
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/threads/thread_options.h
@@ -0,0 +1,107 @@
+/**
+ * \file thread_options.h
+ * \brief
+ *
+ * Copyright (c) 2013, 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_UTILS_THREADS_THREAD_OPTIONS_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_THREAD_OPTIONS_H_
+
+namespace threads {
+
+/**
+ * @breif Startup options for thread.
+ * Look for "threads/thread.h" for example
+ */
+class ThreadOptions {
+ public:
+ /**
+ * Ctor
+ * @param stack_size - thread stack size. If stack size less than
+ * threads::Thread::kMinStackSize the default value is used.
+ * 0 - default stack size for current platform.
+ * @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) {
+ }
+
+ /**
+ * Dtor.
+ */
+ virtual ~ThreadOptions() {
+ }
+
+ /**
+ * Copy ctor.
+ * @param options - new options.
+ */
+ ThreadOptions(const ThreadOptions& options) {
+ *this = options;
+ }
+
+ /**
+ * Assign operator.
+ * @param options - new options.
+ * @return new options.
+ */
+ ThreadOptions& operator=(const ThreadOptions& options ) {
+ stack_size_ = options.stack_size();
+ is_joinable_ = options.is_joinable();
+ return *this;
+ }
+
+ /**
+ * Stack size.
+ * @return Stack size for thread.
+ */
+ size_t stack_size() const {
+ return stack_size_;
+ }
+
+ /**
+ * Is thread joinable?
+ * @return - Returns true if the thread is joinable.
+ */
+ bool is_joinable() const {
+ return is_joinable_;
+ }
+
+ protected:
+ size_t stack_size_;
+ bool is_joinable_;
+};
+
+} // namespace threads
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_THREAD_OPTIONS_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/threads/thread_validator.h b/SDL_Core/src/components/Utils/include/Utils/threads/thread_validator.h
new file mode 100644
index 000000000..def1994b7
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/threads/thread_validator.h
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2013, 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_THREADS_THREAD_VALIDATOR_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_THREADS_THREAD_VALIDATOR_H_
+
+#include "utils/threads/thread.h"
+
+namespace threads {
+/*
+ * Use objects of this class to validate (in run-time) access
+ * to single-threaded objects. It remembers the thread it was
+ * created on and then allows to easily check whether an object is
+ * being accessed from different thread and log an error in that case
+ *
+ * Put a member of type SingleThreadValidator in your class and call
+ * AssertRunningOnCreationThread in it's every public method
+ *
+ * class MySingleThreadedThing {
+ * .....
+ * public:
+ * void DoSomeWork();
+ * .....
+ * private:
+ * SingleThreadValidator thread_validator_;
+ * .....
+ * };
+ *
+ * void MySingleThreadedThing::DoSomeWork() {
+ * thread_validator_.AssertRunningOnCreationThread();
+ * .....
+ * }
+ */
+class SingleThreadSimpleValidator {
+ public:
+ SingleThreadSimpleValidator();
+ ~SingleThreadSimpleValidator();
+
+ // This method should be called in every public method
+ // of classes being checked for absence of concurrent access
+ void AssertRunningOnCreationThread() const;
+ private:
+ const Thread::Id creation_thread_id_;
+};
+
+
+/*
+ * This is bit more sophisticated debug helper which allows
+ * objects being checked to be transferred between threads.
+ * Make sure to pass ownership calling PassToThread before
+ * object is accessed from that thread!
+ *
+ * It's better to virtually inherit it to make PassToThread publicly
+ * available to code that uses objects of your classes and make sure
+ * that if your object consists of different thread-validated
+ * parts you'll need not to call PassToThread proxy method for
+ * every part of your composite object
+ */
+class SingleThreadValidator {
+ public:
+ SingleThreadValidator();
+ ~SingleThreadValidator();
+
+ // Must be called prior to transferring object being validated to
+ // another thread or when passing it back
+ void PassToThread(Thread::Id thread_id) const;
+ // This method should be called in every public method
+ // of classes being checked for absence of unintended concurrent
+ // access
+ void AssertRunningOnValidThread() const;
+ private:
+ mutable Thread::Id owning_thread_id_;
+};
+
+} // namespace threads
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_THREADS_THREAD_VALIDATOR_H_
diff --git a/SDL_Core/src/components/Utils/include/Utils/timer_thread.h b/SDL_Core/src/components/Utils/include/Utils/timer_thread.h
new file mode 100644
index 000000000..0da5616e7
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/Utils/timer_thread.h
@@ -0,0 +1,336 @@
+/**
+ * Copyright (c) 2013, 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_UTILS_TIMER_THREAD
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_TIMER_THREAD
+
+#include <time.h>
+
+#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 {
+
+class TimerDelegate;
+
+/*
+ * The 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 callee A class that use timer
+ * @param f CallBackFunction which will be called on timeout
+ * Atantion! "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 looer,
+ * if true, TimerThread will call "f()" function every time out
+ * until stop()
+ */
+ TimerThread(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 Stops timer execution
+ * Must not be used in callback function!
+ */
+ virtual void stop();
+
+ 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
+ * @param timeout Timeout to be set
+ */
+ TimerDelegate(const TimerThread* timer_thread);
+
+ /*
+ * @brief Destructor
+ */
+ virtual ~TimerDelegate();
+
+ /*
+ * @brief Thread main function.
+ */
+ virtual void threadMain();
+
+ /*
+ * @brief Called by thread::thread to free all allocated resources.
+ */
+ virtual bool exitThreadMain();
+
+ /*
+ * @brief Restart timer
+ *
+ * @param timeout_seconds New timeout to be set
+ */
+ virtual void setTimeOut(uint32_t timeout_seconds);
+
+ protected:
+ const TimerThread* timer_thread_;
+ uint32_t timeout_seconds_;
+ sync_primitives::Lock state_lock_;
+ sync_primitives::ConditionalVariable termination_condition_;
+ volatile bool stop_flag_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TimerDelegate);
+ };
+
+
+ /**
+ * @brief Delegate release looper timer.
+ * Will call delegate every timeot 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
+ */
+ TimerLooperDelegate(const TimerThread* timer_thread);
+
+ /*
+ * @brief Thread main function.
+ */
+ virtual void threadMain();
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TimerLooperDelegate);
+ };
+ void (T::*callback_)();
+ T* callee_;
+ TimerDelegate* delegate_;
+ threads::Thread* thread_;
+ mutable bool is_running_;
+
+ DISALLOW_COPY_AND_ASSIGN(TimerThread);
+};
+
+template <class T>
+TimerThread<T>::TimerThread(T* callee, void (T::*f)(), bool is_looper)
+ : callback_(f),
+ callee_(callee),
+ delegate_(NULL),
+ thread_(NULL),
+ is_running_(false) {
+ if (is_looper) {
+ delegate_ = new TimerLooperDelegate(this);
+ } else {
+ delegate_ = new TimerDelegate(this);
+ }
+
+ if (delegate_) {
+ thread_ = new threads::Thread("TimerThread", delegate_);
+ }
+}
+
+template <class T>
+TimerThread<T>::~TimerThread() {
+ if (is_running_) {
+ stop();
+ }
+ callback_ = NULL;
+ callee_ = NULL;
+ delete thread_;
+ // delegate_ will be deleted by thread_
+ thread_ = NULL;
+ delegate_ = NULL;
+}
+
+template <class T>
+void TimerThread<T>::start(uint32_t timeout_seconds) {
+ if (is_running_) {
+ stop();
+ }
+
+ delegate_->setTimeOut(timeout_seconds);
+ if (delegate_ && thread_) {
+ is_running_ = true;
+ const size_t kStackSize = 16384;
+ thread_->startWithOptions(threads::ThreadOptions(kStackSize));
+ }
+}
+
+template <class T>
+void TimerThread<T>::stop() {
+ if (delegate_ && thread_) {
+ thread_->stop();
+ is_running_ = false;
+ }
+}
+
+template <class T>
+void TimerThread<T>::onTimeOut() const {
+ if (callee_ && callback_) {
+ (callee_->*callback_)();
+ is_running_ = false;
+ }
+}
+
+template <class T>
+TimerThread<T>::TimerDelegate::TimerDelegate(const TimerThread* timer_thread)
+ : timer_thread_(timer_thread),
+ timeout_seconds_(0),
+ stop_flag_(false) {
+ DCHECK(timer_thread_);
+}
+
+template <class T>
+TimerThread<T>::TimerLooperDelegate::TimerLooperDelegate(const 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_);
+ const time_t end_time = time(NULL) + timeout_seconds_;
+ int32_t wait_seconds_left = int32_t(difftime(end_time, time(NULL)));
+ while (!stop_flag_) {
+ // Sleep
+ ConditionalVariable::WaitStatus wait_status =
+ termination_condition_.WaitFor(auto_lock, wait_seconds_left * 1000);
+ wait_seconds_left = int32_t(difftime(end_time, time(NULL)));
+ // Quit sleeping or continue sleeping in case of spurious wake up
+ if (ConditionalVariable::kTimeout == wait_status ||
+ wait_seconds_left <= 0) {
+ break;
+ }
+ }
+ if (!stop_flag_) {
+ timer_thread_->onTimeOut();
+ }
+ stop_flag_ = false;
+}
+
+template <class T>
+void TimerThread<T>::TimerLooperDelegate::threadMain() {
+ using sync_primitives::ConditionalVariable;
+ sync_primitives::AutoLock auto_lock(TimerDelegate::state_lock_);
+ time_t end_time = time(NULL) + TimerDelegate::timeout_seconds_;
+ int32_t wait_seconds_left = int32_t(difftime(end_time, time(NULL)));
+ while (!TimerDelegate::stop_flag_) {
+ // Sleep
+ ConditionalVariable::WaitStatus wait_status =
+ TimerDelegate::termination_condition_.WaitFor(auto_lock, wait_seconds_left * 1000);
+ wait_seconds_left = int32_t(difftime(end_time, time(NULL)));
+ // Quit sleeping or continue sleeping in case of spurious wake up
+ if (ConditionalVariable::kTimeout == wait_status ||
+ wait_seconds_left <= 0) {
+ TimerDelegate::timer_thread_->onTimeOut();
+ end_time = time(NULL) + TimerDelegate::timeout_seconds_;
+ }
+ }
+ TimerDelegate::stop_flag_ = false;
+}
+
+
+template <class T>
+bool TimerThread<T>::TimerDelegate::exitThreadMain() {
+ {
+ sync_primitives::AutoLock auto_lock(state_lock_);
+ stop_flag_ = true;
+ }
+ termination_condition_.NotifyOne();
+ return true;
+}
+
+template <class T>
+void TimerThread<T>::TimerDelegate::setTimeOut(uint32_t timeout_seconds) {
+ timeout_seconds_ = timeout_seconds;
+}
+
+} // namespace timer
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_TIMER_THREAD
diff --git a/SDL_Core/src/components/Utils/include/utils/atomic.h b/SDL_Core/src/components/Utils/include/utils/atomic.h
new file mode 100644
index 000000000..bf5b4baf8
--- /dev/null
+++ b/SDL_Core/src/components/Utils/include/utils/atomic.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2013, 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.
+*/
+
+#ifdef __QNXNTO__
+#include <atomic.h>
+#endif
+
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_ATOMIC_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_ATOMIC_H_
+
+#if defined(__QNXNTO__)
+#define atomic_post_inc(ptr) atomic_add_value((ptr), 1)
+#elif defined(__GNUG__)
+#define atomic_post_inc(ptr) __sync_fetch_and_add((ptr), 1)
+#else
+#warning "atomic_post_inc() implementation is not atomic"
+#define atomic_post_inc(ptr) (*(ptr))++
+#endif
+
+#if defined(__QNXNTO__)
+#define atomic_post_dec(ptr) atomic_sub_value((ptr), 1)
+#elif defined(__GNUG__)
+#define atomic_post_dec(ptr) __sync_fetch_and_sub((ptr), 1)
+#else
+#warning "atomic_post_dec() implementation is not atomic"
+#define atomic_post_dec(ptr) (*(ptr))--
+#endif
+
+#if defined(_QNXNTO__)
+// on QNX pointer assignment is believed to be atomic
+#define atomic_pointer_assign(dst, src) (dst) = (src)
+#elif defined(__GNUG__)
+// with g++ pointer assignment is believed to be atomic
+#define atomic_pointer_assign(dst, src) (dst) = (src)
+#else
+#warning atomic_pointer_assign() implementation may be non-atomic
+#define atomic_pointer_assign(dst, src) (dst) = (src)
+#endif
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_ATOMIC_H_
diff --git a/SDL_Core/src/components/Utils/src/WorkWithOS.cpp b/SDL_Core/src/components/Utils/src/WorkWithOS.cpp
deleted file mode 100644
index 46995fcd4..000000000
--- a/SDL_Core/src/components/Utils/src/WorkWithOS.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
-* \file WorkWithOS.cpp
-* \brief Implementation of general functions for work with OS.
-*/
-
-#include <iostream>
-#include <fstream>
-#include <cstddef>
-#include <algorithm>
-#include <string>
-#include <sstream>
-#include <sys/statvfs.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <unistd.h>
-#include "Utils/WorkWithOS.h"
-
-unsigned long int WorkWithOS::getAvailableSpace()
-{
- char currentAppPath[256];
- memset((void*)currentAppPath, 0, 256);
- getcwd(currentAppPath, 255);
-
- struct statvfs fsInfo;
- memset((void*)&fsInfo, 0, sizeof(fsInfo));
- statvfs(currentAppPath, &fsInfo);
- return fsInfo.f_bsize * fsInfo.f_bfree;
-}
-
-std::string WorkWithOS::getFullPath(const std::string & fileName)
-{
- char currentAppPath[FILENAME_MAX];
- memset(currentAppPath, 0, FILENAME_MAX);
- getcwd(currentAppPath, FILENAME_MAX);
-
- char path[FILENAME_MAX];
- memset(path, 0, FILENAME_MAX);
- snprintf(path, FILENAME_MAX - 1, "%s/%s"
- , currentAppPath, fileName.c_str());
- return std::string(path);
-}
-
-std::string WorkWithOS::createDirectory(const std::string & directoryName)
-{
- if (!checkIfDirectoryExists(directoryName))
- {
- mkdir(directoryName.c_str(), S_IRWXU);
- }
-
- return directoryName;
-}
-
-bool WorkWithOS::checkIfDirectoryExists(const std::string & directoryName)
-{
- struct stat status;
- memset(&status, 0, sizeof(status));
-
- if (-1 == stat(directoryName.c_str(), &status)
- || !S_ISDIR(status.st_mode))
- {
- return false;
- }
-
- return true;
-}
-
-bool WorkWithOS::checkIfFileExists(const std::string & fileName)
-{
- struct stat status;
- memset(&status, 0, sizeof(status));
-
- if (-1 == stat(fileName.c_str(), &status))
- {
- return false;
- }
- return true;
-}
-
-bool WorkWithOS::createFileAndWrite(const std::string & fileName,
- const std::vector<unsigned char>& fileData)
-{
- std::ofstream file(fileName.c_str(), std::ios_base::binary);
- if (file.is_open())
- {
- for (int i = 0; i < fileData.size(); ++i)
- {
- file << fileData[i];
- }
- file.close();
- return true;
- }
- return false;
-}
-
-bool WorkWithOS::deleteFile(const std::string & fileName)
-{
- if (checkIfFileExists(fileName))
- {
- return !remove(fileName.c_str());
- }
- return false;
-}
-
-std::vector<std::string> WorkWithOS::listFilesInDirectory(
- const std::string & directoryName)
-{
- std::vector<std::string> listFiles;
- if (!checkIfDirectoryExists(directoryName))
- {
- return listFiles;
- }
-
- DIR * directory = NULL;
- struct dirent* dirElement = NULL;
- directory = opendir(directoryName.c_str());
- if ( NULL != directory )
- {
- while( dirElement = readdir(directory) )
- {
- if (0 == strcmp(dirElement->d_name, "..")
- || 0 == strcmp(dirElement->d_name, "."))
- {
- continue;
- }
- listFiles.push_back(std::string(dirElement->d_name));
- }
- closedir(directory);
- }
-
- return listFiles;
-}
-
-bool WorkWithOS::readFileAsBinary(const std::string& fileName, std::vector<unsigned char>& v)
-{
- if (!checkIfFileExists(fileName))
- return false;
-
- std::ifstream file(fileName.c_str(), std::ios_base::binary);
- std::ostringstream ss;
- ss << file.rdbuf();
- const std::string& s = ss.str();
-
- v.resize(s.length());
- std::copy(s.begin(), s.end(), v.begin());
- return true;
-}
diff --git a/SDL_Core/src/components/Utils/src/back_trace.cc b/SDL_Core/src/components/Utils/src/back_trace.cc
new file mode 100644
index 000000000..23b1b4d1e
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/back_trace.cc
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+
+#include "utils/back_trace.h"
+
+#include <algorithm>
+#include <vector>
+#include <sstream>
+
+#include <cxxabi.h>
+#include <execinfo.h>
+
+#include "utils/macro.h"
+
+using std::ostream;
+using std::string;
+using std::vector;
+using threads::Thread;
+
+namespace utils {
+
+namespace {
+string demangle(const char* symbol) {
+ char temp[2048];
+ if (1 == sscanf(symbol, "%*[^(]%*[^_]%2047[^)+]", temp)) {
+ size_t size;
+ int32_t status;
+ char* demangled = abi::__cxa_demangle(temp, NULL, &size, &status);
+ if (demangled != NULL) {
+ string result(demangled);
+ free(demangled);
+ return result;
+ }
+ }
+ return symbol;
+}
+}
+
+Backtrace::Backtrace(int32_t count, int32_t skip_top)
+ : thread_id_(threads::Thread::CurrentId()) {
+ int32_t skip = skip_top + 1; // Skip this constructor
+ vector<void*> full_trace (count + skip);
+ int32_t captured = backtrace(&full_trace.front(), count + skip);
+ int32_t first_call = std::min(captured, skip);
+ int32_t last_call = std::min(first_call + count, captured);
+ backtrace_.assign(full_trace.begin() + first_call, full_trace.begin() + last_call);
+}
+
+Backtrace::~Backtrace() {
+}
+
+vector<string> Backtrace::CallStack() const {
+ vector<string> callstack;
+ callstack.reserve(backtrace_.size());
+ char** mangled = backtrace_symbols(&backtrace_.front(), backtrace_.size());
+ for (size_t i = 0; i != backtrace_.size(); ++i) {
+ callstack.push_back(demangle(mangled[i]));
+ }
+ free(mangled);
+ return callstack;
+}
+
+Thread::Id Backtrace::ThreadId() const {
+ return thread_id_;
+}
+
+ostream& operator<< (ostream& os, const Backtrace& bt) {
+ const vector<string> symbols = bt.CallStack();
+ os<<"Stack trace ("<<bt.ThreadId()<<")\n";
+ if (symbols.empty()) {
+ os<<"Not available"<<std::endl;
+ } else for (size_t i = 0; i < symbols.size(); ++i) {
+ os<<symbols[i]<<std::endl;
+ }
+ return os;
+}
+
+} // namespace utils
diff --git a/SDL_Core/src/components/Utils/src/bitstream.cc b/SDL_Core/src/components/Utils/src/bitstream.cc
new file mode 100644
index 000000000..94ee5f8a1
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/bitstream.cc
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+#include "utils/bitstream.h"
+
+namespace utils {
+
+BitStream::BitStream(uint8_t* bytes, size_t bytes_count)
+ : bytes_(bytes),
+ bytes_count_(bytes_count),
+ byte_offset_(0),
+ bit_offset_(0),
+ bad_(false) {
+}
+
+BitStream::~BitStream() {
+}
+
+size_t BitStream::FullBytesLeft() {
+ size_t left = bytes_count_ - byte_offset_;
+ if (bit_offset_ != 0)
+ left -= 1;
+ return left;
+}
+
+size_t BitStream::BitsLeft() {
+ return (bytes_count_ - byte_offset_) * CHAR_BIT - bit_offset_;
+}
+
+void BitStream::ExtractBytes(void* buffer, size_t length) {
+ DCHECK(length == 0 || buffer != NULL);
+ if (IsGood()) {
+ if (bit_offset_ != 0 || // bytes can be extracted only when
+ FullBytesLeft() < length) { // stream is byte-aligned
+ MarkBad();
+ return;
+ }
+ }
+ memcpy(buffer, &bytes_[byte_offset_], length);
+ byte_offset_ += length;
+}
+
+void Extract(BitStream* bs, uint8_t* val) {
+ DCHECK(bs && val);
+ if (*bs) {
+ bs->Extract(*val);
+ }
+}
+
+void Extract(BitStream* bs, uint8_t* val, size_t bits) {
+ DCHECK(bs && val);
+ if (*bs) {
+ bs->ExtractBits(*val, bits);
+ }
+}
+
+void Extract(BitStream* bs, uint32_t* val) {
+ DCHECK(bs && val);
+ if (*bs) {
+ bs->Extract(*val);
+ }
+}
+
+void Extract(BitStream* bs, uint32_t* val, size_t bits) {
+ DCHECK(bs && val);
+ if (*bs) {
+ bs->ExtractBits(*val, bits);
+ }
+}
+
+void Extract(BitStream* bs, std::string* str, size_t length) {
+ DCHECK(bs && str);
+ if (*bs) {
+ // Prevent memory over-allocation
+ if (bs->FullBytesLeft() < length) {
+ bs->MarkBad();
+ return;
+ }
+ str->resize(length+1);
+ void* stringdata = &(*str)[0];
+ bs->ExtractBytes(stringdata, length);
+ str->resize(length);
+ }
+}
+
+void Extract(BitStream* bs, std::vector<uint8_t>* data, size_t length) {
+ DCHECK(bs && data);
+ if (*bs) {
+ // Prevent memory over-allocation
+ if (bs->FullBytesLeft() < length) {
+ bs->MarkBad();
+ return;
+ }
+ data->resize(length);
+ void* dataptr = &data->front();
+ bs->ExtractBytes(dataptr, length);
+ }
+}
+
+} // namespace utils
+
diff --git a/SDL_Core/src/components/Utils/src/conditional_variable_posix.cc b/SDL_Core/src/components/Utils/src/conditional_variable_posix.cc
new file mode 100644
index 000000000..46b31ee7c
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/conditional_variable_posix.cc
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+#include "utils/conditional_variable.h"
+
+#include <errno.h>
+#include <time.h>
+
+#include "utils/lock.h"
+#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 {
+
+ConditionalVariable::ConditionalVariable() {
+ pthread_condattr_t attrs;
+ int32_t initialized = pthread_condattr_init(&attrs);
+ if (initialized != 0)
+ LOG4CXX_ERROR(g_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 "
+ "conditional variable");
+ int32_t rv = pthread_condattr_destroy(&attrs);
+ if (rv != 0)
+ LOG4CXX_ERROR(g_logger, "Failed to destroy "
+ "conditional variable attributes");
+}
+
+ConditionalVariable::~ConditionalVariable() {
+ pthread_cond_destroy(&cond_var_);
+
+}
+
+void ConditionalVariable::NotifyOne() {
+ int32_t signaled = pthread_cond_signal(&cond_var_);
+ if (signaled != 0)
+ LOG4CXX_ERROR(g_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");
+
+}
+
+void ConditionalVariable::Wait(AutoLock& auto_lock) {
+ Lock& lock = auto_lock.GetLock();
+ lock.AssertTakenAndMarkFree();
+ int32_t wait_status = pthread_cond_wait(&cond_var_,
+ &lock.mutex_);
+ lock.AssertFreeAndMarkTaken();
+ if (wait_status != 0)
+ LOG4CXX_ERROR(g_logger, "Failed to wait for conditional variable");
+}
+
+ConditionalVariable::WaitStatus ConditionalVariable::WaitFor(
+ AutoLock& auto_lock, int32_t milliseconds){
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ timespec wait_interval;
+ wait_interval.tv_sec = now.tv_sec +
+ (milliseconds / kMillisecondsPerSecond);
+ wait_interval.tv_nsec = now.tv_nsec +
+ (milliseconds % kMillisecondsPerSecond) * kNanosecondsPerMillisecond;
+ wait_interval.tv_sec += wait_interval.tv_nsec / kNanosecondsPerSecond;
+ wait_interval.tv_nsec %= kNanosecondsPerSecond;
+
+ Lock& lock = auto_lock.GetLock();
+ lock.AssertTakenAndMarkFree();
+ int32_t timedwait_status = pthread_cond_timedwait(&cond_var_,
+ &lock.mutex_,
+ &wait_interval);
+ lock.AssertFreeAndMarkTaken();
+ WaitStatus wait_status = kNoTimeout;
+ switch(timedwait_status) {
+ case 0: {
+ wait_status = kNoTimeout;
+ } break;
+ case EINTR: {
+ wait_status = kNoTimeout;
+ } break;
+ case ETIMEDOUT: {
+ wait_status = kTimeout;
+ } break;
+ default: {
+ LOG4CXX_ERROR(g_logger, "Failed to timewait for conditional variable");
+ }
+ }
+
+ return wait_status;
+}
+
+} // namespace sync_primitives
diff --git a/SDL_Core/src/components/Utils/src/date_time.cc b/SDL_Core/src/components/Utils/src/date_time.cc
new file mode 100644
index 000000000..644e938a9
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/date_time.cc
@@ -0,0 +1,74 @@
+/**
+* \file request_watchdog.h
+* \brief DateTime class source file.
+*
+* Copyright (c) 2013, 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.
+*/
+
+#include <sys/time.h>
+#include <stdint.h>
+#include "utils/date_time.h"
+
+namespace date_time {
+
+int32_t const DateTime::MILLISECONDS_IN_SECOND;
+int32_t const DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+struct timeval DateTime::getCurrentTime() {
+ struct timeval currentTime;
+ struct timezone timeZone;
+
+ gettimeofday(&currentTime, &timeZone);
+
+ return currentTime;
+}
+
+int32_t DateTime::calculateTimeSpan(struct timeval sinceTime) {
+ struct timeval currentTime, timeDifference;
+ struct timezone timeZone;
+
+ gettimeofday(&currentTime, &timeZone);
+
+ timeDifference.tv_sec = currentTime.tv_sec - sinceTime.tv_sec;
+
+ timeDifference.tv_usec = currentTime.tv_usec - sinceTime.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;
+}
+
+} // namespace date_time
diff --git a/SDL_Core/src/components/Utils/src/file_system.cc b/SDL_Core/src/components/Utils/src/file_system.cc
new file mode 100644
index 000000000..2e5b909af
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/file_system.cc
@@ -0,0 +1,404 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+
+#include "utils/file_system.h"
+
+#include <sys/statvfs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <dirent.h>
+#include <unistd.h>
+// TODO(VS): lint error: Streams are highly discouraged.
+#include <fstream>
+#include <cstddef>
+#include <algorithm>
+#include "config_profile/profile.h"
+
+uint64_t file_system::GetAvailableDiskSpace() {
+ char currentAppPath[FILENAME_MAX];
+ memset(reinterpret_cast<void*>(currentAppPath), 0, FILENAME_MAX);
+ getcwd(currentAppPath, FILENAME_MAX - 1);
+
+ struct statvfs fsInfo;
+ memset(reinterpret_cast<void*>(&fsInfo), 0, sizeof(fsInfo));
+ if( statvfs(currentAppPath, &fsInfo) == 0) {
+ return fsInfo.f_bsize * fsInfo.f_bfree;
+ } else {
+ return 0;
+ }
+}
+
+uint32_t file_system::FileSize(const std::string &path) {
+ if (file_system::FileExists(path)) {
+ struct stat file_info;
+ memset(reinterpret_cast<void*>(&file_info), 0, sizeof(file_info));
+ stat(path.c_str(), &file_info);
+ return file_info.st_size;
+ }
+ return 0;
+}
+
+uint32_t file_system::DirectorySize(const std::string& path) {
+ uint32_t size = 0;
+ int32_t return_code = 0;
+ DIR* directory = NULL;
+
+#ifndef __QNXNTO__
+ struct dirent dir_element_;
+ struct dirent* dir_element = &dir_element_;
+#else
+ char* direntbuffer =
+ new char[offsetof(struct dirent, d_name) +
+ pathconf(path.c_str(), _PC_NAME_MAX) + 1];
+ struct dirent* dir_element = new(direntbuffer) dirent;
+#endif
+ struct dirent* result = NULL;
+ struct stat file_info;
+ directory = opendir(path.c_str());
+ if (NULL != directory) {
+ return_code = readdir_r(directory, dir_element, &result);
+ for (; NULL != result && 0 == return_code;
+ return_code = readdir_r(directory, dir_element, &result)) {
+ if (0 == strcmp(result->d_name, "..")
+ || 0 == strcmp(result->d_name, ".")) {
+ continue;
+ }
+ std::string full_element_path = path + "/" + result->d_name;
+ if (file_system::IsDirectory(full_element_path)) {
+ size += DirectorySize(full_element_path);
+ } else {
+ memset(reinterpret_cast<void*>(&file_info), 0, sizeof(file_info));
+ stat(full_element_path.c_str(), &file_info);
+ size += file_info.st_size;
+ }
+ }
+ }
+ closedir(directory);
+#ifdef __QNXNTO__
+ delete[] direntbuffer;
+#endif
+ return size;
+}
+
+uint32_t file_system::GetAvailableSpaceForApp(const std::string& app_name) {
+ const uint32_t app_quota = profile::Profile::instance()->app_dir_quota();
+ if (DirectoryExists(app_name)) {
+ std::string full_path = FullPath(app_name);
+ uint32_t size_of_directory = DirectorySize(full_path);
+ if (app_quota < size_of_directory) {
+ return 0;
+ }
+ uint32_t current_app_quota = app_quota - size_of_directory;
+ uint32_t available_disk_space = GetAvailableDiskSpace();
+ if (current_app_quota > available_disk_space) {
+ return available_disk_space;
+ } else {
+ return current_app_quota;
+ }
+ } else {
+ return app_quota;
+ }
+}
+
+std::string file_system::CreateDirectory(const std::string& name) {
+ if (!DirectoryExists(name)) {
+ mkdir(name.c_str(), S_IRWXU);
+ }
+
+ return name;
+}
+
+bool file_system::IsDirectory(const std::string& name) {
+ struct stat status;
+ memset(&status, 0, sizeof(status));
+
+ if (-1 == stat(name.c_str(), &status)) {
+ return false;
+ }
+
+ return S_ISDIR(status.st_mode);
+}
+
+bool file_system::DirectoryExists(const std::string& name) {
+ struct stat status;
+ memset(&status, 0, sizeof(status));
+
+ if (-1 == stat(name.c_str(), &status) || !S_ISDIR(status.st_mode)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool file_system::FileExists(const std::string& name) {
+ struct stat status;
+ memset(&status, 0, sizeof(status));
+
+ if (-1 == stat(name.c_str(), &status)) {
+ return false;
+ }
+ return true;
+}
+
+bool file_system::Write(
+ const std::string& file_name, const std::vector<uint8_t>& data,
+ std::ios_base::openmode mode) {
+ std::ofstream file(file_name.c_str(), std::ios_base::binary | mode);
+ if (file.is_open()) {
+ for (int32_t i = 0; i < data.size(); ++i) {
+ file << data[i];
+ }
+ file.close();
+ return true;
+ }
+ return false;
+}
+
+
+
+std::ofstream* file_system::Open(const std::string& file_name,
+ std::ios_base::openmode mode) {
+
+
+ std::ofstream* file = new std::ofstream();
+ file->open( file_name.c_str(),std::ios_base::binary | mode);
+ if (file->is_open()) {
+
+ return file;
+ }
+
+ return NULL;
+}
+
+bool file_system::Write(std::ofstream* const file_stream,
+ const uint8_t* data,
+ uint32_t data_size) {
+ bool result = false;
+ if (file_stream) {
+ for (size_t i = 0; i < data_size; ++i) {
+ (*file_stream) << data[i];
+ }
+ result = true;
+ }
+ return result;
+}
+
+void file_system::Close(std::ofstream* file_stream) {
+ if (file_stream) {
+ file_stream->close();
+ }
+}
+
+std::string file_system::FullPath(const std::string& file) {
+ // FILENAME_MAX defined stdio_lim.h was replaced with less value
+ // since it seems, that is caused overflow in some cases
+
+ size_t filename_max_lenght = 1024;
+ char currentAppPath[filename_max_lenght];
+ memset(currentAppPath, 0, filename_max_lenght);
+ getcwd(currentAppPath, filename_max_lenght);
+
+ char path[filename_max_lenght];
+ memset(path, 0, filename_max_lenght);
+ snprintf(path, filename_max_lenght - 1, "%s/%s", currentAppPath, file.c_str());
+ return std::string(path);
+}
+
+bool file_system::DeleteFile(const std::string& name) {
+ if (FileExists(name) && IsAccessible(name, W_OK)) {
+ return !remove(name.c_str());
+ }
+ return false;
+}
+
+void remove_directory_content(const std::string& directory_name) {
+ int32_t return_code = 0;
+ DIR* directory = NULL;
+#ifndef __QNXNTO__
+ struct dirent dir_element_;
+ struct dirent* dir_element = &dir_element_;
+#else
+ char* direntbuffer =
+ new char[offsetof(struct dirent, d_name) +
+ pathconf(directory_name.c_str(), _PC_NAME_MAX) + 1];
+ struct dirent* dir_element = new(direntbuffer) dirent;
+#endif
+ struct dirent* result = NULL;
+
+ directory = opendir(directory_name.c_str());
+
+ if (NULL != directory) {
+ return_code = readdir_r(directory, dir_element, &result);
+
+ for (; NULL != result && 0 == return_code;
+ return_code = readdir_r(directory, dir_element, &result)) {
+ if (0 == strcmp(result->d_name, "..")
+ || 0 == strcmp(result->d_name, ".")) {
+ continue;
+ }
+
+ std::string full_element_path = directory_name + "/" + result->d_name;
+
+ if (file_system::IsDirectory(full_element_path)) {
+ remove_directory_content(full_element_path);
+ rmdir(full_element_path.c_str());
+ } else {
+ remove(full_element_path.c_str());
+ }
+ }
+ }
+
+ closedir(directory);
+#ifdef __QNXNTO__
+ delete[] direntbuffer;
+#endif
+}
+
+bool file_system::RemoveDirectory(const std::string& directory_name,
+ bool is_recursively) {
+ if (DirectoryExists(directory_name)
+ && IsAccessible(directory_name, W_OK)) {
+ if (is_recursively) {
+ remove_directory_content(directory_name);
+ }
+
+ return !rmdir(directory_name.c_str());
+ }
+ return false;
+}
+
+bool file_system::IsAccessible(const std::string& name, int32_t how) {
+ return !access(name.c_str(), how);
+}
+
+std::vector<std::string> file_system::ListFiles(
+ const std::string& directory_name) {
+ std::vector<std::string> listFiles;
+ if (!DirectoryExists(directory_name)) {
+ return listFiles;
+ }
+
+ int32_t return_code = 0;
+ DIR* directory = NULL;
+#ifndef __QNXNTO__
+ struct dirent dir_element_;
+ struct dirent* dir_element = &dir_element_;
+#else
+ char* direntbuffer =
+ new char[offsetof(struct dirent, d_name) +
+ pathconf(directory_name.c_str(), _PC_NAME_MAX) + 1];
+ struct dirent* dir_element = new(direntbuffer) dirent;
+#endif
+ struct dirent* result = NULL;
+
+ directory = opendir(directory_name.c_str());
+ if (NULL != directory) {
+ return_code = readdir_r(directory, dir_element, &result);
+
+ for (; NULL != result && 0 == return_code;
+ return_code = readdir_r(directory, dir_element, &result)) {
+ if (0 == strcmp(result->d_name, "..")
+ || 0 == strcmp(result->d_name, ".")) {
+ continue;
+ }
+
+ listFiles.push_back(std::string(result->d_name));
+ }
+
+ closedir(directory);
+#ifdef __QNXNTO__
+ delete[] direntbuffer;
+#endif
+ }
+
+ return listFiles;
+}
+
+bool file_system::ReadBinaryFile(const std::string& name,
+ std::vector<uint8_t>& result) {
+ if (!FileExists(name) || !IsAccessible(name, R_OK)) {
+ return false;
+ }
+
+ std::ifstream file(name.c_str(), std::ios_base::binary);
+ std::ostringstream ss;
+ ss << file.rdbuf();
+ const std::string& s = ss.str();
+
+ result.resize(s.length());
+ std::copy(s.begin(), s.end(), result.begin());
+ return true;
+}
+
+bool file_system::ReadFile(const std::string& name, std::string& result) {
+ if (!FileExists(name) || !IsAccessible(name, R_OK)) {
+ return false;
+ }
+
+ std::ifstream file(name.c_str());
+ std::ostringstream ss;
+ ss << file.rdbuf();
+ result = ss.str();
+ return true;
+}
+
+const std::string file_system::ConvertPathForURL(const std::string& path) {
+ std::string::const_iterator it_path = path.begin();
+ std::string::const_iterator it_path_end = path.end();
+
+ const std::string reserved_symbols = "!#$&'()*+,:;=?@[] ";
+ std::string::const_iterator it_sym = reserved_symbols.begin();
+ std::string::const_iterator it_sym_end = reserved_symbols.end();
+
+ std::string converted_path;
+ while (it_path != it_path_end) {
+
+ it_sym = reserved_symbols.begin();
+ for (; it_sym != it_sym_end; ++it_sym) {
+
+ if (*it_path == *it_sym) {
+ size_t size = 100;
+ char percent_value[size];
+ snprintf(percent_value, size, "%%%x", *it_path);
+ converted_path += percent_value;
+ ++it_path;
+ continue;
+ }
+ }
+
+ converted_path += *it_path;
+ ++it_path;
+ }
+
+ return converted_path;
+}
diff --git a/SDL_Core/src/components/Utils/src/lock_posix.cc b/SDL_Core/src/components/Utils/src/lock_posix.cc
new file mode 100644
index 000000000..be292f3e6
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/lock_posix.cc
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+
+#include "utils/lock.h"
+
+#include <errno.h>
+
+#include "utils/logger.h"
+
+namespace {
+log4cxx::LoggerPtr g_logger =
+ log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
+}
+
+namespace sync_primitives {
+
+Lock::Lock()
+#ifndef NDEBUG
+ : lock_taken_(false)
+#endif // NDEBUG
+{
+ int32_t status = pthread_mutex_init(&mutex_, NULL);
+ if (status != 0) {
+ LOG4CXX_ERROR(g_logger, "Failed to initialize mutex");
+ }
+}
+
+Lock::~Lock() {
+#ifndef NDEBUG
+ if (lock_taken_) {
+ LOG4CXX_ERROR(g_logger, "Destroying non-released mutex");
+ }
+#endif
+ int32_t status = pthread_mutex_destroy(&mutex_);
+ if (status != 0) {
+ LOG4CXX_ERROR(g_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");
+ }
+ AssertFreeAndMarkTaken();
+}
+
+void Lock::Release() {
+ AssertTakenAndMarkFree();
+ int32_t status = pthread_mutex_unlock(&mutex_);
+ if (status != 0) {
+ LOG4CXX_ERROR(g_logger, "Failed to unlock mutex");
+ }
+}
+
+bool Lock::Try() {
+ bool ackquired = false;
+#ifndef NDEBUG
+ if (lock_taken_) {
+ LOG4CXX_ERROR(g_logger, "Trying to lock already taken mutex");
+ }
+#endif
+ switch(pthread_mutex_trylock(&mutex_)) {
+ case 0: {
+ ackquired = true;
+#ifndef NDEBUG
+ lock_taken_ = true;
+#endif
+ } break;
+ case EBUSY: {
+ ackquired = false;
+ } break;
+ default: {
+ ackquired = false;
+ LOG4CXX_ERROR(g_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");
+ }
+ lock_taken_ = true;
+}
+void Lock::AssertTakenAndMarkFree() {
+ if (!lock_taken_) {
+ LOG4CXX_ERROR(g_logger, "Unlocking a mutex that is not taken");
+ }
+ lock_taken_ = false;
+}
+#endif
+
+
+} // namespace sync_primitives
diff --git a/SDL_Core/src/components/Utils/src/signals_linux.cc b/SDL_Core/src/components/Utils/src/signals_linux.cc
new file mode 100644
index 000000000..1821f6fbe
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/signals_linux.cc
@@ -0,0 +1,57 @@
+/**
+* \file signals.cc
+* \brief Signal (i.e. SIGINT) handling.
+* Copyright (c) 2013, 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.
+*/
+#include <csignal>
+#include <stdint.h>
+
+namespace utils {
+
+bool SubscribeToTerminateSignal(void (*func)(int32_t p)) {
+ void (*prev_func)(int32_t p);
+
+ prev_func = signal(SIGINT, func);
+ return (SIG_ERR != prev_func);
+}
+
+bool ResetSubscribeToTerminateSignal() {
+ void (*prev_func)(int32_t p);
+ prev_func = signal(SIGINT, SIG_DFL);
+ return (SIG_ERR != prev_func);
+}
+
+void ForwardSignal() {
+ int32_t signal_id = SIGINT;
+ raise(signal_id);
+}
+
+} // namespace utils
diff --git a/SDL_Core/src/components/Utils/src/threads/posix_thread.cc b/SDL_Core/src/components/Utils/src/threads/posix_thread.cc
new file mode 100644
index 000000000..e59fedc2a
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/threads/posix_thread.cc
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+
+#include <limits.h>
+#include <stddef.h>
+
+#include "utils/threads/thread.h"
+#include "utils/threads/thread_manager.h"
+
+using namespace std;
+using namespace threads::impl;
+
+namespace {
+static void* threadFunc(void* closure) {
+ threads::ThreadDelegate* delegate =
+ static_cast<threads::ThreadDelegate*>(closure);
+ delegate->threadMain();
+ return NULL;
+}
+}
+
+namespace threads {
+size_t Thread::kMinStackSize = PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */
+log4cxx::LoggerPtr Thread::logger_ =
+ log4cxx::LoggerPtr(log4cxx::Logger::getLogger("threads::Thread"));
+
+bool Thread::Id::operator==(const Thread::Id other) const {
+ return pthread_equal(id_, other.id_) != 0;
+}
+
+// static
+Thread::Id Thread::CurrentId() {
+ return Id(pthread_self());
+}
+
+//static
+std::string Thread::NameFromId(Id thread_id) {
+ return ThreadManager::instance()->GetName(thread_id.id_);
+}
+
+//static
+void Thread::SetNameForId(Id thread_id, const std::string& name) {
+ ThreadManager::instance()->RegisterName(thread_id.id_, name);
+}
+
+
+Thread::Thread(const char* name, ThreadDelegate* delegate)
+ : name_("undefined"),
+ delegate_(delegate),
+ thread_handle_(0),
+ thread_options_(),
+ isThreadRunning_(false) {
+ if (name) {
+ name_ = name;
+ }
+}
+
+Thread::~Thread() {
+ ThreadManager::instance()->Unregister(thread_handle_);
+ if (delegate_) {
+ delete delegate_;
+ }
+}
+
+bool Thread::start() {
+ return startWithOptions(thread_options_);
+}
+
+bool Thread::startWithOptions(const ThreadOptions& options) {
+ if (!delegate_) {
+ NOTREACHED();
+ return false;
+ }
+
+ thread_options_ = options;
+
+ bool success = false;
+ pthread_attr_t attributes;
+ int pthread_result = pthread_attr_init(&attributes);
+ if (pthread_result != 0) {
+ LOG4CXX_INFO(logger_,"Couldn't init pthread attributes."
+ " Error code = " << pthread_result);
+ }
+ if (!thread_options_.is_joinable()) {
+ pthread_result = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
+ if (pthread_result != 0) {
+ LOG4CXX_INFO(logger_,"Couldn't set detach state attribute. Error code = " << pthread_result);
+ }
+ }
+
+ // 0 - default value
+ if (thread_options_.stack_size() > 0
+ && thread_options_.stack_size() >= Thread::kMinStackSize) {
+ pthread_result = pthread_attr_setstacksize(&attributes, thread_options_.stack_size());
+ if (pthread_result != 0) {
+ LOG4CXX_INFO(logger_,"Couldn't set stacksize = " << thread_options_.stack_size() <<
+ "Error code = " << pthread_result);
+ }
+ }
+ success = !pthread_create(&thread_handle_, &attributes, threadFunc,
+ delegate_);
+ if (success) {
+ pthread_result = pthread_setname_np(thread_handle_, name_.c_str());
+# ifdef __QNXNTO__
+ if (pthread_result != EOK) {
+ LOG4CXX_INFO(logger_,"Couldn't set pthread name"
+ " Error code = " << pthread_result);
+ }
+# endif
+ LOG4CXX_INFO(logger_,"Created thread: " << name_);
+ ThreadManager::instance()->RegisterName(thread_handle_, name_);
+ }
+
+ isThreadRunning_ = success;
+
+ pthread_result = pthread_attr_destroy(&attributes);
+ if (pthread_result != 0) {
+ LOG4CXX_INFO(logger_,"Couldn't destroy pthread attributes."
+ " Error code = " << pthread_result);
+ }
+ return success;
+}
+
+void Thread::stop() {
+ if (!is_running()) {
+ return;
+ }
+
+ if (NULL != delegate_) {
+ if (!delegate_->exitThreadMain()) {
+ if (thread_handle_ != pthread_self()) {
+ pthread_cancel(thread_handle_);
+ }
+ }
+ }
+
+ // Wait for the thread to exit. It should already have terminated but make
+ // sure this assumption is valid.
+
+ join();
+}
+
+void Thread::join() {
+ int pthread_result = pthread_join(thread_handle_, NULL);
+ if (pthread_result != 0) {
+ LOG4CXX_INFO(logger_,"Couldn't join thread "
+ " Error code = " << pthread_result);
+ }
+ isThreadRunning_ = false;
+}
+
+std::ostream& operator<<(std::ostream& os, Thread::Id thread_id) {
+ return os<<Thread::NameFromId(thread_id);
+}
+
+} // namespace threads
diff --git a/SDL_Core/src/components/Utils/src/threads/thread_manager.cc b/SDL_Core/src/components/Utils/src/threads/thread_manager.cc
new file mode 100644
index 000000000..e4b96aa51
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/threads/thread_manager.cc
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+
+#include "utils/threads/thread_manager.h"
+
+#include <sstream>
+
+#if defined(OS_LINUX)
+#include <sys/syscall.h>
+#include <unistd.h>
+#endif
+
+namespace threads {
+namespace impl {
+using namespace std;
+using namespace sync_primitives;
+
+namespace {
+
+const char* kUnknownName = "UnnamedThread";
+
+log4cxx::LoggerPtr g_logger =
+ log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
+
+} // namespace
+
+UnnamedThreadRegistry::UnnamedThreadRegistry() {
+
+}
+
+UnnamedThreadRegistry::~UnnamedThreadRegistry() {
+
+}
+
+std::string UnnamedThreadRegistry::GetUniqueName(PlatformThreadHandle id) {
+ AutoLock auto_lock(state_lock_);
+ IdNameMap::iterator found = id_number_.find(id);
+ if (found != id_number_.end()) {
+ return found->second;
+ } else {
+ ++last_thread_number_;
+ std::stringstream namestream;
+ namestream<<kUnknownName<<last_thread_number_;
+ return id_number_[id] = namestream.str();
+ }
+}
+
+ThreadManager::ThreadManager() {
+ names_.insert(kUnknownName);
+}
+
+ThreadManager::~ThreadManager() {
+}
+
+void ThreadManager::RegisterName(PlatformThreadHandle id, const string& name) {
+ AutoLock auto_lock(state_lock_);
+ if (names_.count(name) == 0) {
+ names_.insert(name);
+ 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
+ <<", but it is already registered with name "
+ <<inserted.first->second);
+ }
+ } else {
+ LOG4CXX_ERROR(g_logger, "Ignoring duplicate thread name: " + name);
+ }
+}
+
+string ThreadManager::GetName(PlatformThreadHandle id) const {
+ AutoLock auto_lock(state_lock_);
+ IdNamesMap::const_iterator found = id_names_.find(id);
+ if (found != id_names_.end()) {
+ return found->second;
+ } else {
+ LOG4CXX_WARN(g_logger, "Thread doesn't have associated name");
+ return unnamed_thread_namer_.GetUniqueName(id);
+ }
+}
+
+void ThreadManager::Unregister(PlatformThreadHandle id) {
+ AutoLock auto_lock(state_lock_);
+ string name = id_names_[id];
+ names_.erase(name);
+ id_names_.erase(id);
+}
+
+
+} // namespace impl
+} // namespace threads
diff --git a/SDL_Core/src/components/Utils/src/threads/thread_validator.cc b/SDL_Core/src/components/Utils/src/threads/thread_validator.cc
new file mode 100644
index 000000000..5bc66f138
--- /dev/null
+++ b/SDL_Core/src/components/Utils/src/threads/thread_validator.cc
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+#include "utils/threads/thread_validator.h"
+
+#include "utils/logger.h"
+#include "utils/back_trace.h"
+
+namespace threads {
+
+namespace {
+log4cxx::LoggerPtr g_logger =
+ log4cxx::LoggerPtr(log4cxx::Logger::getLogger("Utils"));
+}
+
+SingleThreadSimpleValidator::SingleThreadSimpleValidator()
+ : creation_thread_id_(Thread::CurrentId()) {
+}
+
+SingleThreadSimpleValidator::~SingleThreadSimpleValidator() {
+}
+
+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 "
+ << creation_thread_id_
+ <<" is accessed from thread "
+ << current_id
+#ifdef BACKTRACE_SUPPORT
+ << "\n"
+ << utils::Backtrace()
+#endif
+ );
+ }
+}
+
+
+SingleThreadValidator::SingleThreadValidator()
+ : owning_thread_id_(Thread::CurrentId()){
+}
+
+SingleThreadValidator::~SingleThreadValidator() {
+}
+
+void SingleThreadValidator::PassToThread(Thread::Id thread_id) const {
+ owning_thread_id_ = thread_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 "
+ << owning_thread_id_
+ << " is accessed from thread "
+ << current_id << "\n"
+#ifdef BACKTRACE_SUPPORT
+ << utils::Backtrace()
+#endif
+ );
+ }
+}
+
+
+} // namespace threads
+
+// vim: set ts=2 sw=2 et: