summaryrefslogtreecommitdiff
path: root/src/components/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/utils')
-rw-r--r--src/components/utils/CMakeLists.txt64
-rw-r--r--src/components/utils/include/utils/appenders_loader.h51
-rw-r--r--src/components/utils/include/utils/back_trace.h75
-rw-r--r--src/components/utils/include/utils/bitstream.h170
-rw-r--r--src/components/utils/include/utils/file_system.h241
-rw-r--r--src/components/utils/include/utils/log_message_loop_thread.h80
-rw-r--r--src/components/utils/include/utils/resource_usage.h168
-rw-r--r--src/components/utils/include/utils/signals.h41
-rw-r--r--src/components/utils/include/utils/singleton.h179
-rw-r--r--src/components/utils/include/utils/stl_utils.h81
-rw-r--r--src/components/utils/include/utils/system.h93
-rw-r--r--src/components/utils/include/utils/threads/pulse_thread_delegate.h96
-rw-r--r--src/components/utils/include/utils/threads/thread_manager.h117
-rw-r--r--src/components/utils/include/utils/threads/thread_validator.h105
-rw-r--r--src/components/utils/src/appenders_loader.cc55
-rw-r--r--src/components/utils/src/back_trace.cc107
-rw-r--r--src/components/utils/src/bitstream.cc132
-rw-r--r--src/components/utils/src/conditional_variable_posix.cc136
-rw-r--r--src/components/utils/src/date_time.cc102
-rw-r--r--src/components/utils/src/file_system.cc423
-rw-r--r--src/components/utils/src/lock_posix.cc150
-rw-r--r--src/components/utils/src/log_message_loop_thread.cc56
-rw-r--r--src/components/utils/src/logger_status.cc39
-rw-r--r--src/components/utils/src/push_log.cc68
-rw-r--r--src/components/utils/src/resource_usage.cc192
-rw-r--r--src/components/utils/src/rwlock_posix.cc70
-rw-r--r--src/components/utils/src/signals_linux.cc50
-rw-r--r--src/components/utils/src/system.cc167
-rw-r--r--src/components/utils/src/threads/posix_thread.cc259
-rw-r--r--src/components/utils/src/threads/pulse_thread_delegate.cc116
-rw-r--r--src/components/utils/src/threads/thread_manager.cc115
-rw-r--r--src/components/utils/src/threads/thread_validator.cc92
-rw-r--r--src/components/utils/test/CMakeLists.txt17
-rw-r--r--src/components/utils/test/date_time_test.cc128
-rw-r--r--src/components/utils/test/file_system_test.cc111
-rw-r--r--src/components/utils/test/main.cc7
36 files changed, 4153 insertions, 0 deletions
diff --git a/src/components/utils/CMakeLists.txt b/src/components/utils/CMakeLists.txt
new file mode 100644
index 0000000000..12c70746d7
--- /dev/null
+++ b/src/components/utils/CMakeLists.txt
@@ -0,0 +1,64 @@
+set(UtilsIncludeDir ${CMAKE_SOURCE_DIR}/src/components/utils/include)
+
+include_directories (
+ ./include
+ ../config_profile/include
+ ../media_manager/include/
+ ../protocol_handler/include/
+ ${LOG4CXX_INCLUDE_DIRECTORY}
+)
+
+set (SOURCES
+ ./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/rwlock_posix.cc
+ ./src/date_time.cc
+ ./src/signals_linux.cc
+ ./src/system.cc
+ ./src/resource_usage.cc
+ ./src/appenders_loader.cc
+)
+
+if(ENABLE_LOG)
+ list(APPEND SOURCES
+ ./src/push_log.cc
+ ./src/log_message_loop_thread.cc
+ ./src/logger_status.cc
+ )
+endif()
+
+if (BUILD_BACKTRACE_SUPPORT)
+ list(APPEND SOURCES
+ ./src/back_trace.cc
+ )
+endif()
+
+if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
+ list(APPEND SOURCES
+ ./src/threads/pulse_thread_delegate.cc
+ )
+endif()
+
+add_library("Utils" ${SOURCES})
+
+if(ENABLE_LOG)
+ list(APPEND LIBRARIES log4cxx -L${LOG4CXX_LIBS_DIRECTORY})
+ list(APPEND LIBRARIES apr-1 -L${APR_LIBS_DIRECTORY})
+ list(APPEND LIBRARIES aprutil-1 -L${APR_UTIL_LIBS_DIRECTORY})
+ target_link_libraries("Utils" ${LIBRARIES})
+ ADD_DEPENDENCIES(Utils install-3rd_party_logger)
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ target_link_libraries("Utils" pthread ${RTLIB})
+endif()
+
+if(BUILD_TESTS)
+ add_subdirectory(test)
+endif()
+
diff --git a/src/components/utils/include/utils/appenders_loader.h b/src/components/utils/include/utils/appenders_loader.h
new file mode 100644
index 0000000000..03d3217994
--- /dev/null
+++ b/src/components/utils/include/utils/appenders_loader.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_APPENDERS_LOADER_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_APPENDERS_LOADER_H_
+
+namespace utils {
+
+class AppendersLoader {
+ public:
+ AppendersLoader();
+ ~AppendersLoader();
+ bool Loaded() const;
+ private:
+ void* handle_;
+};
+
+extern AppendersLoader appenders_loader;
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_APPENDERS_LOADER_H_
diff --git a/src/components/utils/include/utils/back_trace.h b/src/components/utils/include/utils/back_trace.h
new file mode 100644
index 0000000000..7f8912faf9
--- /dev/null
+++ b/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/src/components/utils/include/utils/bitstream.h b/src/components/utils/include/utils/bitstream.h
new file mode 100644
index 0000000000..cba15abd8b
--- /dev/null
+++ b/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/src/components/utils/include/utils/file_system.h b/src/components/utils/include/utils/file_system.h
new file mode 100644
index 0000000000..d68ec484f9
--- /dev/null
+++ b/src/components/utils/include/utils/file_system.h
@@ -0,0 +1,241 @@
+/**
+ * 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>
+
+namespace file_system {
+
+
+/**
+ * @brief Get available disc space.
+ *
+ * @param path to directory
+ * @return free disc space.
+ */
+uint64_t GetAvailableDiskSpace(const std::string& path);
+
+/*
+ * @brief Get size of current directory
+ *
+ * @param path to directory
+ */
+size_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
+ */
+int64_t FileSize(const std::string& path);
+
+/**
+ * @brief Creates directory
+ * @param name path to directory
+ * @return path to created directory.
+ */
+std::string CreateDirectory(const std::string& name);
+
+/**
+ * @brief Creates directory recursively
+ * @param path - full path to directory
+ * @return return true if directory was created or already exist
+ */
+bool CreateDirectoryRecursively(const std::string& path);
+
+/**
+ * @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 current working directory path
+ * If filename begins with "/", return unchanged filename
+ * @param name file name
+ * @return returns full file path.
+ */
+std::string CurrentWorkingDirectory();
+
+/**
+ * @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 Check access rights for writing
+ *
+ * @param name path to file or folder
+ * @return returns true if has access rights.
+ */
+bool IsWritingAllowed(const std::string& name);
+
+/**
+ * @brief Check access rights for reading
+ *
+ * @param name path to file.
+ * @return returns true if file has access rights.
+ */
+bool IsReadingAllowed(const std::string& name);
+
+/**
+ * @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 Creates or overwrites file with given binary contents
+ * @param name path to the file
+ * @param contents data to be written into the file
+ * @returns true if file write succeeded
+ */
+bool WriteBinaryFile(const std::string& name,
+ const std::vector<uint8_t>& contents);
+
+/**
+ * @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);
+
+/**
+ * @brief Create empty file
+ *
+ * @param name path to file
+ * @return if result success return true
+*/
+bool CreateFile(const std::string& path);
+
+void remove_directory_content(const std::string& directory_name);
+
+} // namespace file_system
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_FILE_SYSTEM_H_
diff --git a/src/components/utils/include/utils/log_message_loop_thread.h b/src/components/utils/include/utils/log_message_loop_thread.h
new file mode 100644
index 0000000000..b23a246e13
--- /dev/null
+++ b/src/components/utils/include/utils/log_message_loop_thread.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOG_MESSAGE_LOOP_THREAD_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOG_MESSAGE_LOOP_THREAD_H_
+
+#include <string>
+#include <queue>
+#include <log4cxx/logger.h>
+
+#include "utils/threads/message_loop_thread.h"
+#include "utils/singleton.h"
+
+namespace logger {
+
+typedef struct {
+ log4cxx::LoggerPtr logger;
+ log4cxx::LevelPtr level;
+ std::string entry;
+ log4cxx_time_t timeStamp;
+ log4cxx::spi::LocationInfo location;
+ log4cxx::LogString threadName;
+} LogMessage;
+
+typedef std::queue<LogMessage> LogMessageQueue;
+
+typedef threads::MessageLoopThread<LogMessageQueue> LogMessageLoopThreadTemplate;
+
+class LogMessageHandler : public LogMessageLoopThreadTemplate::Handler {
+ public:
+ virtual void Handle(const LogMessage message) OVERRIDE;
+};
+
+class LogMessageLoopThread :
+ public LogMessageLoopThreadTemplate,
+ public utils::Singleton<LogMessageLoopThread> {
+
+ public:
+ ~LogMessageLoopThread();
+
+ private:
+ LogMessageLoopThread();
+
+DISALLOW_COPY_AND_ASSIGN(LogMessageLoopThread);
+FRIEND_BASE_SINGLETON_CLASS(LogMessageLoopThread);
+
+};
+
+} // namespace logger
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_LOG_MESSAGE_LOOP_THREAD_H_
diff --git a/src/components/utils/include/utils/resource_usage.h b/src/components/utils/include/utils/resource_usage.h
new file mode 100644
index 0000000000..a8fa4aa7d9
--- /dev/null
+++ b/src/components/utils/include/utils/resource_usage.h
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_RESOURCE_USAGE_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_RESOURCE_USAGE_H_
+
+#include <sys/resource.h>
+#if defined(__QNXNTO__)
+#include <sys/procfs.h>
+#endif
+
+#include <string>
+#include <iostream>
+
+#include "utils/logger.h"
+
+#define MAX_COMM_LEN 128
+#define MAX_CMDLINE_LEN 128
+
+namespace utils {
+
+struct ResourseUsage {
+ long long int utime;
+ long long int stime;
+ long long int memory;
+};
+
+class Resources {
+ public:
+ typedef uint32_t MemInfo;
+#if defined(__QNXNTO__)
+ typedef procfs_info PidStats;
+
+#elif defined(OS_LINUX)
+
+ struct PidStats {
+ int pid;
+ char comm[MAX_COMM_LEN];
+ char state;
+ int ppid;
+ int pgrp;
+ int session;
+ int tty_nr;
+ int tpgid;
+ unsigned int flags;
+ unsigned long minflt;
+ unsigned long cminflt;
+ unsigned long majflt;
+ unsigned long cmajflt;
+ unsigned long utime;
+ long stime;
+ long cutime;
+ long cstime;
+ long priority;
+ long nice;
+ long num_threads;
+ long itrealvalue;
+ unsigned long long starttime;
+ unsigned long vsize;
+ long rss;
+ unsigned long rsslim;
+ unsigned long startcode;
+ unsigned long endcode;
+ unsigned long startstack;
+ unsigned long kstkesp;
+ unsigned long kstkeip;
+ unsigned long signal;
+ unsigned long blocked;
+ unsigned long sigignore;
+ unsigned long sigcatch;
+ unsigned long wchan;
+ unsigned long nswap;
+ unsigned long cnswap;
+ int exit_signal;
+ int processor;
+ unsigned int rt_priority;
+ unsigned int policy;
+ unsigned long long delayacct_blkio_ticks;
+ unsigned long guest_time;
+ long int cguest_time;
+ };
+#else
+
+#endif
+ public:
+ /*
+ * @brief Returns current resource usage of process
+ * @return Raw pointer on ResourseUsage if success, otherwise return NULL
+ */
+ static ResourseUsage* getCurrentResourseUsage();
+
+private:
+
+ /*
+ * @brief reads /proc/PID/stat file on linux
+ * do not work on QNX ( return false, output wan't be changed )
+ * @param output - storage for result string ( there will be separated content of /proc/PID/stat )
+ * @return true on succes false onb fail
+ */
+ static bool ReadStatFile(std::string& output);
+
+ /*
+ * @brief Grab information about curent process
+ * @param output - storage for result struct
+ * @return true on succes false onb fail
+ */
+ static bool GetProcInfo(PidStats& output);
+
+ /*
+ * @brief Grab process memory information
+ * @param output - storage for result struct
+ * @return true on succes false onb fail
+ */
+ static bool GetMemInfo(MemInfo& output);
+
+ /*
+ * @brief return path to /proc/PID/stat file on linux
+ * return path to /proc/PID/as file on linux
+ * @return path to file
+ */
+ static std::string GetStatPath();
+
+ /*
+ * @brief return path to /proc/PID directry
+ * @return path to dir
+ */
+ static std::string GetProcPath();
+
+ /*
+ * path to /proc/ directory
+ */
+ static const char* proc;
+};
+
+}
+
+
+
+#endif /* SRC_COMPONENTS_UTILS_INCLUDE_UTILS_RESOURCE_USAGE_H_ */
diff --git a/src/components/utils/include/utils/signals.h b/src/components/utils/include/utils/signals.h
new file mode 100644
index 0000000000..28e8afd9d6
--- /dev/null
+++ b/src/components/utils/include/utils/signals.h
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2014, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SIGNALS_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SIGNALS_H_
+
+namespace utils {
+bool SubscribeToTerminateSignal(void (*func)(int32_t p));
+bool ResetSubscribeToTerminateSignal();
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SIGNALS_H_
diff --git a/src/components/utils/include/utils/singleton.h b/src/components/utils/include/utils/singleton.h
new file mode 100644
index 0000000000..d7b625e0a1
--- /dev/null
+++ b/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 "utils/lock.h"
+#include "utils/memory_barrier.h"
+#include "utils/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.Acquire();
+ 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.Acquire();
+ 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/src/components/utils/include/utils/stl_utils.h b/src/components/utils/include/utils/stl_utils.h
new file mode 100644
index 0000000000..f525c6429f
--- /dev/null
+++ b/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/src/components/utils/include/utils/system.h b/src/components/utils/include/utils/system.h
new file mode 100644
index 0000000000..16bdc03673
--- /dev/null
+++ b/src/components/utils/include/utils/system.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_H_
+
+#include <string>
+#include <vector>
+
+namespace utils {
+
+/**
+ * Class to execute shell scripts
+ */
+class System {
+ public:
+ /**
+ * Constructs instantiation
+ * @param command name of command for executing
+ */
+ explicit System(const std::string& command);
+
+ /**
+ * Constructs instantiation
+ * @param file name of file for executing
+ * @param command name of command
+ */
+ System(const std::string& file, const std::string& command);
+
+ /**
+ * Adds argument
+ * @param arg argument of command
+ * @return itself object
+ */
+ System& Add(const std::string& arg);
+
+ /**
+ * Executes command as new child process
+ * @return true if success
+ */
+ bool Execute();
+
+ /**
+ * Executes command
+ * @param wait if this flag is true then wait until command is terminated
+ * @return true if success
+ */
+ bool Execute(bool wait);
+
+ private:
+ /**
+ * Command for executing
+ */
+ std::string command_;
+
+ /**
+ * List of arguments
+ */
+ std::vector<std::string> argv_;
+};
+
+} // utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_H_
diff --git a/src/components/utils/include/utils/threads/pulse_thread_delegate.h b/src/components/utils/include/utils/threads/pulse_thread_delegate.h
new file mode 100644
index 0000000000..bb109bde94
--- /dev/null
+++ b/src/components/utils/include/utils/threads/pulse_thread_delegate.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_PULSE_THREAD_DELEGATE_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_PULSE_THREAD_DELEGATE_H_
+
+#include <sys/neutrino.h>
+
+#include "utils/threads/thread_delegate.h"
+
+namespace threads {
+
+/**
+ * @brief This ThreadDelegate derivative is designed
+ * to implement threads waiting for QNX Pulse messages
+ * When constucted, an instance of this class creates QNX channel and connects to it
+ * In exitThreadMain() channel is disconnected and destroyed
+ * In threadMain() endless loop event is armed via pure virtual method ArmEvent()
+ * and thread blocks on MsgReceivePulse() waiting for Pulse
+ * When Pulse comes, OnPulse() pure virtual method is invoked
+ * Subclassed must implement ArmEvent() for events of interest
+ * and OnPulse() for reaction on such events
+ */
+class PulseThreadDelegate : public ThreadDelegate {
+ public:
+/**
+ * @brief default constructor
+ */
+ PulseThreadDelegate();
+ virtual void threadMain();
+ virtual bool exitThreadMain();
+
+ protected:
+/**
+ * @brief This method is to be implemented to arm events of interest
+ * @param event pointer to structure sigevent
+ * @return If this method returns true, thread is blocked on MsgReceivePulse() waiting for Pulse
+ */
+ virtual bool ArmEvent(struct sigevent* event) = 0;
+/**
+ * @brief This method is invoked from threadMain() when Pulse comes
+ */
+ virtual void OnPulse() = 0;
+
+ /**
+ * This method is to be initialize child class
+ * @return If this method returns false, thread will be stopped
+ */
+ virtual bool Init() { return true; }
+
+/**
+ * Finalizes thread
+ * Can free resources
+ */
+ virtual void Finalize() {}
+
+ private:
+ enum {PULSE_CODE = _PULSE_CODE_MINAVAIL + 1};
+
+ bool run_;
+ int chid_;
+ int coid_;
+};
+
+} // namespace threads
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_THREADS_PULSE_THREAD_DELEGATE_H_
diff --git a/src/components/utils/include/utils/threads/thread_manager.h b/src/components/utils/include/utils/threads/thread_manager.h
new file mode 100644
index 0000000000..03330170e1
--- /dev/null
+++ b/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/src/components/utils/include/utils/threads/thread_validator.h b/src/components/utils/include/utils/threads/thread_validator.h
new file mode 100644
index 0000000000..def1994b76
--- /dev/null
+++ b/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/src/components/utils/src/appenders_loader.cc b/src/components/utils/src/appenders_loader.cc
new file mode 100644
index 0000000000..cbbd039060
--- /dev/null
+++ b/src/components/utils/src/appenders_loader.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dlfcn.h>
+
+#include "utils/appenders_loader.h"
+
+namespace utils {
+
+AppendersLoader appenders_loader;
+
+AppendersLoader::AppendersLoader() {
+ handle_ = dlopen("libappenders.so", RTLD_LAZY | RTLD_NODELETE);
+}
+
+AppendersLoader::~AppendersLoader() {
+ if (handle_ != 0) {
+ dlclose(handle_);
+ }
+}
+
+bool AppendersLoader::Loaded() const {
+ return handle_ != 0;
+}
+
+} // namespace utils
diff --git a/src/components/utils/src/back_trace.cc b/src/components/utils/src/back_trace.cc
new file mode 100644
index 0000000000..23b1b4d1e9
--- /dev/null
+++ b/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/src/components/utils/src/bitstream.cc b/src/components/utils/src/bitstream.cc
new file mode 100644
index 0000000000..c616b1ae4a
--- /dev/null
+++ b/src/components/utils/src/bitstream.cc
@@ -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.
+ */
+#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);
+
+ if (0 != length) {
+ void* dataptr = &data->front();
+ bs->ExtractBytes(dataptr, length);
+ }
+ }
+}
+
+} // namespace utils
+
diff --git a/src/components/utils/src/conditional_variable_posix.cc b/src/components/utils/src/conditional_variable_posix.cc
new file mode 100644
index 0000000000..a89f8cab65
--- /dev/null
+++ b/src/components/utils/src/conditional_variable_posix.cc
@@ -0,0 +1,136 @@
+/**
+ * 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 {
+const long kNanosecondsPerSecond = 1000000000;
+const long kMillisecondsPerSecond = 1000;
+const long kNanosecondsPerMillisecond = 1000000;
+}
+
+namespace sync_primitives {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+ConditionalVariable::ConditionalVariable() {
+ pthread_condattr_t attrs;
+ int32_t initialized = pthread_condattr_init(&attrs);
+ if (initialized != 0)
+ LOG4CXX_ERROR(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(logger_, "Failed to initialize "
+ "conditional variable");
+ int32_t rv = pthread_condattr_destroy(&attrs);
+ if (rv != 0)
+ LOG4CXX_ERROR(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(logger_, "Failed to signal conditional variable");
+
+}
+
+void ConditionalVariable::Broadcast() {
+ int32_t signaled = pthread_cond_broadcast(&cond_var_);
+ if (signaled != 0)
+ LOG4CXX_ERROR(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(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(logger_, "Failed to timewait for conditional variable timedwait_status: " << timedwait_status);
+ }
+ }
+
+ return wait_status;
+}
+
+} // namespace sync_primitives
diff --git a/src/components/utils/src/date_time.cc b/src/components/utils/src/date_time.cc
new file mode 100644
index 0000000000..f190951647
--- /dev/null
+++ b/src/components/utils/src/date_time.cc
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2014, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <sys/time.h>
+#include <stdint.h>
+#include "utils/date_time.h"
+
+namespace date_time {
+
+TimevalStruct DateTime::getCurrentTime() {
+ TimevalStruct currentTime;
+ timezone timeZone;
+
+ gettimeofday(&currentTime, &timeZone);
+
+ return currentTime;
+}
+
+int64_t date_time::DateTime::getSecs(const TimevalStruct &time) {
+ return static_cast<int64_t>(time.tv_sec);
+}
+
+int64_t DateTime::getmSecs(const TimevalStruct &time) {
+ return static_cast<int64_t>(time.tv_sec) * MILLISECONDS_IN_SECOND
+ + time.tv_usec / MICROSECONDS_IN_MILLISECONDS;
+}
+
+int64_t DateTime::getuSecs(const TimevalStruct &time) {
+ return static_cast<int64_t>(time.tv_sec) * MILLISECONDS_IN_SECOND
+ * MICROSECONDS_IN_MILLISECONDS + time.tv_usec;
+}
+
+int64_t DateTime::calculateTimeSpan(const TimevalStruct& sinceTime) {
+ return calculateTimeDiff(getCurrentTime(), sinceTime);
+}
+
+int64_t DateTime::calculateTimeDiff(const TimevalStruct &time1,
+ const TimevalStruct &time2){
+ TimevalStruct ret;
+ if (Greater(time1, time2)) {
+ ret = Sub(time1, time2);
+ } else {
+ ret = Sub(time2, time1);
+ }
+ return getmSecs(ret);
+}
+
+TimevalStruct DateTime::Sub(const TimevalStruct& time1,
+ const TimevalStruct& time2) {
+ TimevalStruct ret;
+ timersub(&time1, &time2, &ret);
+ return ret;
+}
+
+bool DateTime::Greater(const TimevalStruct& time1, const TimevalStruct& time2) {
+ return timercmp(&time1, &time2, >);
+}
+
+bool DateTime::Less(const TimevalStruct& time1, const TimevalStruct& time2) {
+ return timercmp(&time1, &time2, <);
+}
+
+bool DateTime::Equal(const TimevalStruct& time1, const TimevalStruct& time2) {
+ return !timercmp(&time1, &time2, !=);
+}
+
+TimeCompare date_time::DateTime::compareTime(const TimevalStruct &time1, const TimevalStruct &time2) {
+ if (Greater(time1, time2)) return GREATER;
+ if (Less(time1, time2)) return LESS;
+ return EQUAL;
+}
+
+} // namespace date_time
diff --git a/src/components/utils/src/file_system.cc b/src/components/utils/src/file_system.cc
new file mode 100644
index 0000000000..5eb2457a09
--- /dev/null
+++ b/src/components/utils/src/file_system.cc
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/file_system.h"
+#include "utils/logger.h"
+
+#include <sys/statvfs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sstream>
+
+#include <dirent.h>
+#include <unistd.h>
+// TODO(VS): lint error: Streams are highly discouraged.
+#include <fstream>
+#include <cstddef>
+#include <algorithm>
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+uint64_t file_system::GetAvailableDiskSpace(const std::string& path) {
+ struct statvfs fsInfo;
+ memset(reinterpret_cast<void*>(&fsInfo), 0, sizeof(fsInfo));
+ if (statvfs(path.c_str(), &fsInfo) == 0) {
+ return fsInfo.f_bsize * fsInfo.f_bfree;
+ } else {
+ return 0;
+ }
+}
+
+int64_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;
+}
+
+size_t file_system::DirectorySize(const std::string& path) {
+ size_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;
+}
+
+std::string file_system::CreateDirectory(const std::string& name) {
+ if (!DirectoryExists(name)) {
+ mkdir(name.c_str(), S_IRWXU);
+ }
+
+ return name;
+}
+
+bool file_system::CreateDirectoryRecursively(const std::string& path) {
+ size_t pos = 0;
+ bool ret_val = true;
+
+ while (ret_val == true && pos <= path.length()) {
+ pos = path.find('/', pos + 1);
+ if (!DirectoryExists(path.substr(0, pos))) {
+ if (0 != mkdir(path.substr(0, pos).c_str(), S_IRWXU)) {
+ ret_val = false;
+ }
+ }
+ }
+
+ return ret_val;
+}
+
+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 (uint32_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::CurrentWorkingDirectory() {
+ size_t filename_max_lenght = 1024;
+ char currentAppPath[filename_max_lenght];
+ memset(currentAppPath, 0, filename_max_lenght);
+ if (0 == getcwd(currentAppPath, filename_max_lenght)) {
+ LOG4CXX_WARN(logger_, "Could not get CWD");
+ }
+
+ char path[filename_max_lenght];
+ memset(path, 0, filename_max_lenght);
+ snprintf(path, filename_max_lenght - 1, "%s", currentAppPath);
+ 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 file_system::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);
+}
+
+bool file_system::IsWritingAllowed(const std::string& name) {
+ return IsAccessible(name, W_OK);
+}
+
+bool file_system::IsReadingAllowed(const std::string& name) {
+ return IsAccessible(name, R_OK);
+}
+
+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::WriteBinaryFile(const std::string& name,
+ const std::vector<uint8_t>& contents) {
+ using namespace std;
+ ofstream output(name.c_str(), ios_base::binary|ios_base::trunc);
+ output.write(reinterpret_cast<const char*>(&contents.front()),
+ contents.size());
+ return output.good();
+}
+
+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;
+}
+
+bool file_system::CreateFile(const std::string& path) {
+ std::ofstream file(path);
+ if (!(file.is_open())) {
+ return false;
+ } else {
+ file.close();
+ return true;
+ }
+}
diff --git a/src/components/utils/src/lock_posix.cc b/src/components/utils/src/lock_posix.cc
new file mode 100644
index 0000000000..7591d4b525
--- /dev/null
+++ b/src/components/utils/src/lock_posix.cc
@@ -0,0 +1,150 @@
+/**
+ * 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 <stdint.h>
+
+#include "utils/logger.h"
+
+namespace sync_primitives {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+Lock::Lock()
+#ifndef NDEBUG
+ : lock_taken_(0),
+ is_mutex_recursive_(false)
+#endif // NDEBUG
+{
+ int32_t status = pthread_mutex_init(&mutex_, NULL);
+ if (status != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to initialize mutex");
+ }
+}
+
+Lock::Lock(bool is_mutex_recursive)
+#ifndef NDEBUG
+ : lock_taken_(0),
+ is_mutex_recursive_(is_mutex_recursive)
+#endif // NDEBUG
+{
+ int32_t status;
+
+ if (is_mutex_recursive) {
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ status = pthread_mutex_init(&mutex_, &attr);
+ } else {
+ status = pthread_mutex_init(&mutex_, NULL);
+ }
+
+ if (status != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to initialize mutex");
+ }
+}
+
+Lock::~Lock() {
+#ifndef NDEBUG
+ if (lock_taken_ > 0) {
+ LOG4CXX_ERROR(logger_, "Destroying non-released mutex");
+ }
+#endif
+ int32_t status = pthread_mutex_destroy(&mutex_);
+ if (status != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to destroy mutex");
+ }
+}
+
+void Lock::Acquire() {
+ int32_t status = pthread_mutex_lock(&mutex_);
+ if (status != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to acquire mutex");
+ }
+ AssertFreeAndMarkTaken();
+}
+
+void Lock::Release() {
+ AssertTakenAndMarkFree();
+ int32_t status = pthread_mutex_unlock(&mutex_);
+ if (status != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to unlock mutex");
+ }
+}
+
+bool Lock::Try() {
+ bool ackquired = false;
+#ifndef NDEBUG
+ if ((lock_taken_ > 0) && !is_mutex_recursive_) {
+ LOG4CXX_ERROR(logger_, "Trying to lock already taken not recurcive mutex");
+ }
+#endif
+ switch(pthread_mutex_trylock(&mutex_)) {
+ case 0: {
+ ackquired = true;
+#ifndef NDEBUG
+ lock_taken_++;
+#endif
+ } break;
+ case EBUSY: {
+ ackquired = false;
+ } break;
+ default: {
+ ackquired = false;
+ LOG4CXX_ERROR(logger_, "Failed to try lock the mutex");
+ }
+ }
+ return ackquired;
+}
+
+#ifndef NDEBUG
+void Lock::AssertFreeAndMarkTaken() {
+ if ((lock_taken_ > 0) && !is_mutex_recursive_) {
+ LOG4CXX_ERROR(logger_, "Locking already taken not recurcive mutex");
+ NOTREACHED();
+ }
+ lock_taken_++;
+}
+void Lock::AssertTakenAndMarkFree() {
+ if (lock_taken_ == 0) {
+ LOG4CXX_ERROR(logger_, "Unlocking a mutex that is not taken");
+ NOTREACHED();
+ }
+ lock_taken_--;
+}
+#endif
+
+
+} // namespace sync_primitives
diff --git a/src/components/utils/src/log_message_loop_thread.cc b/src/components/utils/src/log_message_loop_thread.cc
new file mode 100644
index 0000000000..1403a5f712
--- /dev/null
+++ b/src/components/utils/src/log_message_loop_thread.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/log_message_loop_thread.h"
+#include "utils/logger_status.h"
+
+namespace logger {
+
+void LogMessageHandler::Handle(const LogMessage message) {
+ message.logger->forcedLog(message.level,
+ message.entry,
+ message.timeStamp,
+ message.location,
+ message.threadName);
+}
+
+LogMessageLoopThread::LogMessageLoopThread() :
+ LogMessageLoopThreadTemplate("Logger", new LogMessageHandler()) {
+}
+
+LogMessageLoopThread::~LogMessageLoopThread() {
+// we'll have to drop messages
+// while deleting logger thread
+ logger_status = DeletingLoggerThread;
+}
+
+} // namespace logger
diff --git a/src/components/utils/src/logger_status.cc b/src/components/utils/src/logger_status.cc
new file mode 100644
index 0000000000..be341b9add
--- /dev/null
+++ b/src/components/utils/src/logger_status.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/logger_status.h"
+
+namespace logger {
+
+LoggerStatus logger_status = LoggerThreadNotCreated;
+
+} // namespace logger
diff --git a/src/components/utils/src/push_log.cc b/src/components/utils/src/push_log.cc
new file mode 100644
index 0000000000..49525a4f27
--- /dev/null
+++ b/src/components/utils/src/push_log.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/push_log.h"
+#include "utils/log_message_loop_thread.h"
+#include "utils/logger_status.h"
+
+namespace logger {
+
+bool push_log(log4cxx::LoggerPtr logger,
+ log4cxx::LevelPtr level,
+ const std::string& entry,
+ log4cxx_time_t timeStamp,
+ const log4cxx::spi::LocationInfo& location,
+ const log4cxx::LogString& threadName
+ ) {
+ if (LoggerThreadCreated == logger_status) {
+ LogMessage message = {logger, level, entry, timeStamp, location, threadName};
+ LogMessageLoopThread::instance()->PostMessage(message);
+ return true;
+ }
+
+ if (LoggerThreadNotCreated == logger_status) {
+ logger_status = CreatingLoggerThread;
+// we'll have to drop messages
+// while creating logger thread
+ LogMessage message = {logger, level, entry, timeStamp, location, threadName};
+ LogMessageLoopThread::instance()->PostMessage(message);
+ logger_status = LoggerThreadCreated;
+ return true;
+ }
+
+// also we drop messages
+// while deleting logger thread
+
+ return false;
+}
+
+} // namespace logger
diff --git a/src/components/utils/src/resource_usage.cc b/src/components/utils/src/resource_usage.cc
new file mode 100644
index 0000000000..aaa9c1b4a7
--- /dev/null
+++ b/src/components/utils/src/resource_usage.cc
@@ -0,0 +1,192 @@
+#include "utils/resource_usage.h"
+#if defined(__QNXNTO__)
+#include <dirent.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sys/neutrino.h>
+#include <sys/procfs.h>
+#include <sys/stat.h>
+#include <sys/trace.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+#include <sys/resource.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sstream>
+#include "utils/file_system.h"
+
+namespace utils {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+const char* Resources::proc = "/proc/";
+
+ResourseUsage* Resources::getCurrentResourseUsage() {
+ PidStats pid_stats;
+ if (false == GetProcInfo(pid_stats)) {
+ LOG4CXX_ERROR(logger_, "Failed to get cpu proc info");
+ return NULL;
+ }
+ MemInfo mem_info;
+ if (false == GetMemInfo(mem_info)) {
+ LOG4CXX_ERROR(logger_, "Failed to get memory info");
+ return NULL;
+ }
+ ResourseUsage* usage = new ResourseUsage();
+ usage->utime = pid_stats.utime;
+ usage->stime = pid_stats.stime;
+ usage->memory = static_cast<long long int>(mem_info);
+ return usage;
+}
+
+bool Resources::ReadStatFile(std::string& output) {
+ std::string filename = GetStatPath();
+ if (false == file_system::FileExists(filename)) {
+ return false;
+ }
+ if (false == file_system::ReadFile(filename,output)) {
+ return false;
+ }
+ return true;
+}
+
+bool Resources::GetProcInfo(Resources::PidStats& output) {
+#if defined(OS_LINUX)
+ std::string proc_buf;
+ if (false == ReadStatFile(proc_buf)) {
+ return false;
+ }
+ uint32_t num_succes = sscanf(proc_buf.c_str(),
+ "%d" //pid
+ " %*s"//com
+ " %c" //state
+ " %d" //ppid
+ " %d" //pgrp
+ " %d" //session
+ " %d" //tty_nr
+ " %d" //tpgid
+ " %u" //flags
+ " %lu" //minflt
+ " %lu" //cminflt
+ " %lu" //majflt
+ " %lu" //cmajflt
+ " %lu" //utime
+ " %lu" //stime
+ " %ld" //cutime
+ " %ld" //cstime
+ " %ld" //priority
+ " %ld" //nice
+ " %ld" //num_threads
+ " %ld" //itrealvalue
+ " %llu" //starttime
+ " %lu" //vsize
+ " %ld" //rss
+ " %lu" //rsslim
+ " %lu" //startcode
+ " %lu" //endcode
+ " %lu" //startstack
+ " %lu" //kstkesp
+ " %lu" //kstkip
+ " %lu" //signal
+ " %lu" //blocked
+ " %lu" //sigignore
+ " %lu" //sigcatch
+ " %lu" //wchan
+ " %lu" //nswap
+ " %lu" //cnswap
+ " %d" //exit_signal
+ " %d" //processor
+ " %u" //rt_priority
+ " %u" //policy
+ " %llu" //delayacct_blkio_ticks
+ " %lu" //guest_time
+ " %ld" //cguest_time
+ ,&(output.pid), &(output.state), &(output.ppid), &(output.pgrp), &(output.session),
+ &(output.tty_nr), &(output.tpgid), &(output.flags), &(output.minflt), &(output.cminflt),
+ &(output.majflt), &(output.cmajflt), &(output.utime), &(output.stime), &(output.cutime),
+ &(output.cstime), &(output.priority), &( output.nice), &(output.num_threads), &(output.itrealvalue),
+ &(output.starttime), &(output.vsize), &(output.rss), &(output.rsslim), &(output.startcode),
+ &(output.endcode), &(output.startstack), &(output.kstkesp), &(output.kstkeip), &(output.signal),
+ &(output.blocked), &(output.sigignore), &(output.sigcatch), &(output.wchan), &(output.nswap),
+ &(output.cnswap), &(output.exit_signal), &(output.processor), &(output.rt_priority), &(output.policy),
+ &(output.delayacct_blkio_ticks), &(output.guest_time), &(output.cguest_time)
+ );
+ if(num_succes != 43) { // 43 is number of iteams in Resources::PidStats
+ LOG4CXX_ERROR(logger_, "Couldn't parse all iteams in /proc/PID/stat file");
+ return false;
+ }
+ return true;
+#elif defined(__QNXNTO__)
+ int fd = open(GetProcPath().c_str(), O_RDONLY);
+ if (0 >= fd) {
+ LOG4CXX_ERROR(logger_, "Failed open process proc file : " << GetProcPath() <<
+ "; error no : " << strerror( errno ) );
+ return false;
+ }
+ devctl(fd, DCMD_PROC_INFO, &output, sizeof(output), 0);
+ close(fd);
+ return true;
+#endif
+}
+
+bool Resources::GetMemInfo(Resources::MemInfo &output) {
+ bool result = false;
+ #if defined(OS_LINUX)
+ Resources::PidStats pid_stat;
+ if (false == GetProcInfo(pid_stat)) {
+ LOG4CXX_ERROR(logger_, "Failed to get proc info");
+ result = false;
+ } else {
+ output = pid_stat.vsize;
+ result = true;
+ }
+
+#elif defined(__QNXNTO__)
+ std::string as_path = GetStatPath();
+ struct stat st;
+ struct _dir* proc_dir = 0;
+ struct dirent* proc_entry = 0;
+ if (0 == (proc_dir = opendir(proc))) {
+ LOG4CXX_ERROR(logger_, "Unable to access to " << proc);
+ result = false;
+ return result;
+ }
+ if (0 == (proc_entry = readdir(proc_dir))) {
+ LOG4CXX_ERROR(logger_, "Unable to read : " << proc_dir);
+ result = false;
+ return result;
+ }
+ closedir(proc_dir);
+ if (-1 == stat(as_path.c_str(), &st) || 0 == st.st_size) {
+ LOG4CXX_ERROR(logger_, "Unable to stat : " << as_path.c_str());
+ result = false;
+ return result;
+ }
+ output = st.st_size;
+ result = true;
+#endif
+ return result;
+}
+
+std::string Resources::GetStatPath() {
+ std::string filename;
+#if defined(OS_LINUX)
+ filename = GetProcPath() + "/stat";
+#elif defined(__QNXNTO__)
+ filename = GetProcPath() + "/as";
+#endif
+ return filename;
+}
+
+std::string Resources::GetProcPath() {
+ char buffer[1024];
+ pid_t my_pid = getpid();
+ snprintf(buffer, sizeof(buffer), "%s%d/", proc , my_pid);
+ std::string filename(buffer);
+ return filename;
+}
+
+} // namespace utils
diff --git a/src/components/utils/src/rwlock_posix.cc b/src/components/utils/src/rwlock_posix.cc
new file mode 100644
index 0000000000..7cc850b25b
--- /dev/null
+++ b/src/components/utils/src/rwlock_posix.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/rwlock.h"
+#include "utils/logger.h"
+
+namespace sync_primitives {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+RWLock::RWLock() {
+ if (pthread_rwlock_init(&rwlock_, 0) != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to initialize rwlock");
+ }
+}
+
+RWLock::~RWLock() {
+ if (pthread_rwlock_destroy(&rwlock_) != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to destroy rwlock");
+ }
+}
+
+void RWLock::AcquireForReading() {
+ if (pthread_rwlock_rdlock(&rwlock_) != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to acquire rwlock for reading");
+ }
+}
+
+void RWLock::AcquireForWriting() {
+ if (pthread_rwlock_wrlock(&rwlock_) != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to acquire rwlock for writing");
+ }
+}
+
+void RWLock::Release() {
+ if (pthread_rwlock_unlock(&rwlock_) != 0) {
+ LOG4CXX_ERROR(logger_, "Failed to release rwlock");
+ }
+}
+
+} // namespace sync_primitives
diff --git a/src/components/utils/src/signals_linux.cc b/src/components/utils/src/signals_linux.cc
new file mode 100644
index 0000000000..f592a1e22b
--- /dev/null
+++ b/src/components/utils/src/signals_linux.cc
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2014, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#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);
+}
+
+} // namespace utils
diff --git a/src/components/utils/src/system.cc b/src/components/utils/src/system.cc
new file mode 100644
index 0000000000..ee90315db0
--- /dev/null
+++ b/src/components/utils/src/system.cc
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef __QNX__
+# include <process.h>
+#else // __QNX__
+# include <sys/types.h>
+# include <sys/wait.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <unistd.h>
+#endif // __QNX__
+
+#include <algorithm>
+#include <functional>
+#include <cstring>
+
+#include "utils/logger.h"
+#include "utils/system.h"
+
+namespace utils {
+
+CREATE_LOGGERPTR_LOCAL(logger_, "Utils")
+
+struct GetCString {
+ char * operator ()(const std::string& string) {
+ return const_cast<char*>(string.c_str());
+ }
+};
+
+System::System(const std::string& command)
+ : command_(command) {
+ argv_.push_back(command);
+}
+
+System::System(const std::string& file, const std::string& command)
+ : command_(file) {
+ argv_.push_back(command);
+}
+
+bool System::Execute() {
+ return Execute(false);
+}
+
+System& System::Add(const std::string& arg) {
+ argv_.push_back(arg);
+ return *this;
+}
+
+#ifdef __QNX__
+
+bool System::Execute(bool wait) {
+ size_t size = argv_.size();
+ char * *argv = new char*[size + 1];
+ std::transform(argv_.begin(), argv_.end(), argv, GetCString());
+ argv[size] = NULL;
+
+ int mode = wait ? P_WAIT : P_NOWAIT;
+ int ret = spawnvp(mode, command_.c_str(), argv);
+ delete[] argv;
+
+ if (ret == -1) {
+ LOG4CXX_ERROR(logger_, "Can't execute command: " << command_
+ << " Errno is: " << std::strerror(errno));
+ return false;
+ }
+
+ if (wait) {
+ return WEXITSTATUS(ret) == 0;
+ }
+
+ return true;
+}
+
+#else // __QNX__
+
+bool System::Execute(bool wait) {
+ // Create a child process.
+ pid_t pid_command = fork();
+
+ switch (pid_command) {
+ case -1: { // Error
+ LOG4CXX_FATAL(logger_, "fork() failed!");
+ return false;
+ }
+ case 0: { // Child process
+ int32_t fd_dev0 = open("/dev/null", O_RDWR, S_IWRITE);
+ if (0 > fd_dev0) {
+ LOG4CXX_FATAL(logger_, "Open dev0 failed!");
+ return false;
+ }
+ // close input/output file descriptors.
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+
+ // move input/output to /dev/null.
+ dup2(fd_dev0, STDIN_FILENO);
+ dup2(fd_dev0, STDOUT_FILENO);
+ dup2(fd_dev0, STDERR_FILENO);
+
+ size_t size = argv_.size();
+ char * *argv = new char*[size + 1];
+ std::transform(argv_.begin(), argv_.end(), argv, GetCString());
+ argv[size] = NULL;
+
+ // Execute the program.
+ if (execvp(command_.c_str(), argv) == -1) {
+ LOG4CXX_ERROR(logger_, "Can't execute command: " << command_);
+ _exit(EXIT_FAILURE);
+ }
+ delete[] argv;
+
+ return true;
+ }
+ default: { /* Parent process */
+ LOG4CXX_INFO(logger_, "Process created with pid " << pid_command);
+ if (wait) {
+ int status;
+ pid_t wait_pid;
+ do {
+ wait_pid = waitpid(pid_command, &status, WUNTRACED | WCONTINUED);
+ if (wait_pid == -1) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Can't wait");
+ _exit(EXIT_FAILURE);
+ return false;
+ }
+ } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+ return WEXITSTATUS(status) == 0;
+ }
+
+ return true;
+ }
+ }
+}
+
+#endif // __QNX__
+
+} // utils
diff --git a/src/components/utils/src/threads/posix_thread.cc b/src/components/utils/src/threads/posix_thread.cc
new file mode 100644
index 0000000000..faaadd673c
--- /dev/null
+++ b/src/components/utils/src/threads/posix_thread.cc
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#include <limits.h>
+#include <stddef.h>
+#include <signal.h>
+
+#include "utils/threads/thread.h"
+#include "utils/threads/thread_manager.h"
+#include "utils/logger.h"
+#include "pthread.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;
+}
+
+static pthread_t main_thread_id;
+static bool main_thread_id_set = false;
+
+#ifndef __QNXNTO__
+ const int EOK = 0;
+#endif
+
+#if defined(OS_POSIX)
+ const size_t THREAD_NAME_SIZE = 15;
+#endif
+}
+
+namespace threads {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+size_t Thread::kMinStackSize = PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */
+
+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(const Id& thread_id) {
+ return ThreadManager::instance()->GetName(thread_id.id_);
+}
+
+//static
+void Thread::SetNameForId(const Id& thread_id, const std::string& name) {
+ ThreadManager::instance()->RegisterName(thread_id.id_, name);
+
+ const std::string striped_name =
+ name.length() > THREAD_NAME_SIZE ? std::string(name.begin(), name.begin() + THREAD_NAME_SIZE) : name;
+
+ const int pthread_result = pthread_setname_np(thread_id.id_, striped_name.c_str());
+ if (pthread_result != EOK) {
+ LOG4CXX_WARN(logger_,"Couldn't set pthread name \"" << striped_name
+ << "\", error code " << pthread_result <<
+ " (" << strerror(pthread_result) << ")");
+ }
+}
+
+//static
+void Thread::SetMainThread() {
+ main_thread_id = pthread_self();
+ main_thread_id_set = true;
+}
+
+//static
+bool Thread::InterruptMainThread() {
+ if (!main_thread_id_set) {
+ LOG4CXX_WARN(logger_, "Cannot interrupt main thread: not specified");
+ return false;
+ }
+ pthread_kill(main_thread_id, SIGINT);
+ return true;
+}
+
+//static
+void Thread::MaskSignals() {
+ sigset_t sigset;
+ sigfillset(&sigset);
+ pthread_sigmask(SIG_SETMASK, &sigset, 0);
+}
+
+//static
+void Thread::UnmaskSignals() {
+ sigset_t sigset;
+ sigemptyset(&sigset);
+ pthread_sigmask(SIG_SETMASK, &sigset, 0);
+}
+
+Thread::Thread(const char* name, ThreadDelegate* delegate)
+ : name_(name ? name : "undefined"),
+ delegate_(delegate),
+ thread_handle_(0),
+ thread_options_(),
+ isThreadRunning_(false) {
+}
+
+Thread::~Thread() {
+ ThreadManager::instance()->Unregister(thread_handle_);
+ delete delegate_;
+ LOG4CXX_INFO(logger_,"Deleted thread: " << name_);
+}
+
+bool Thread::start() {
+ return startWithOptions(thread_options_);
+}
+
+bool Thread::startWithOptions(const ThreadOptions& options) {
+ LOG4CXX_TRACE_ENTER(logger_);
+ if (!delegate_) {
+ NOTREACHED();
+ LOG4CXX_ERROR(logger_, "NULL delegate");
+ LOG4CXX_TRACE_EXIT(logger_);
+ return false;
+ }
+
+ thread_options_ = options;
+
+ pthread_attr_t attributes;
+ int pthread_result = pthread_attr_init(&attributes);
+ if (pthread_result != EOK) {
+ LOG4CXX_WARN(logger_,"Couldn't init pthread attributes. Error code = "
+ << pthread_result << "(\"" << strerror(pthread_result) << "\")");
+ }
+
+ if (!thread_options_.is_joinable()) {
+ pthread_result = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
+ if (pthread_result != EOK) {
+ LOG4CXX_WARN(logger_,"Couldn't set detach state attribute.. Error code = "
+ << pthread_result << "(\"" << strerror(pthread_result) << "\")");
+ }
+ }
+
+ const size_t stack_size = thread_options_.stack_size();
+ if (stack_size >= Thread::kMinStackSize) {
+ pthread_result = pthread_attr_setstacksize(&attributes, stack_size);
+ if (pthread_result != EOK) {
+ LOG4CXX_WARN(logger_,"Couldn't set stacksize = " << stack_size <<
+ ". Error code = " << pthread_result << "(\""
+ << strerror(pthread_result) << "\")");
+ }
+ }
+
+ pthread_result = pthread_create(&thread_handle_, &attributes, threadFunc, delegate_);
+ isThreadRunning_ = (pthread_result == EOK);
+ if (!isThreadRunning_) {
+ LOG4CXX_WARN(logger_, "Couldn't create thread. Error code = "
+ << pthread_result << "(\"" << strerror(pthread_result) << "\")");
+ } else {
+ LOG4CXX_INFO(logger_,"Created thread: " << name_);
+ SetNameForId(Id(thread_handle_), name_);
+ }
+ LOG4CXX_TRACE_EXIT(logger_);
+ return isThreadRunning_;
+}
+
+void Thread::stop() {
+ LOG4CXX_TRACE_ENTER(logger_);
+ LOG4CXX_DEBUG(logger_, "Canceling thread (#" << thread_handle_
+ << " \"" << name_ << "\") from #" << pthread_self());
+ if (!is_running()) {
+ LOG4CXX_WARN(logger_, "Thread (#" << thread_handle_
+ << " \"" << name_ << "\") is not running");
+ LOG4CXX_TRACE_EXIT(logger_);
+ return;
+ }
+
+ // TODO (EZamakhov): why exitThreadMain return bool and stop does not?
+ if (delegate_ && !delegate_->exitThreadMain()) {
+ if (pthread_self() == thread_handle_) {
+ LOG4CXX_ERROR(logger_,
+ "Couldn't cancel the same thread (#" << thread_handle_
+ << "\"" << name_ << "\")");
+ } else {
+ const int pthread_result = pthread_cancel(thread_handle_);
+ if (pthread_result != EOK) {
+ LOG4CXX_WARN(logger_,
+ "Couldn't cancel thread (#" << thread_handle_ << " \"" << name_ <<
+ "\") from thread #" << pthread_self() << ". Error code = "
+ << pthread_result << " (\"" << strerror(pthread_result) << "\")");
+ }
+ }
+ }
+
+ // Wait for the thread to exit. It should already have terminated but make
+ // sure this assumption is valid.
+ join();
+ LOG4CXX_TRACE_EXIT(logger_);
+}
+
+void Thread::join() {
+ LOG4CXX_TRACE_ENTER(logger_);
+ LOG4CXX_DEBUG(logger_, "Join thread (#" << thread_handle_
+ << " \"" << name_ << "\") from #" << pthread_self());
+ if (thread_handle_ == pthread_self()) {
+ LOG4CXX_ERROR(logger_,
+ "Couldn't join with the same thread (#" << thread_handle_
+ << " \"" << name_ << "\")");
+ } else {
+ const int pthread_result = pthread_join(thread_handle_, NULL);
+ if (pthread_result != EOK) {
+ LOG4CXX_WARN(logger_,
+ "Couldn't join thread (#" << thread_handle_ << " \"" << name_ <<
+ "\") from thread #" << pthread_self() << ". Error code = "
+ << pthread_result << "(\"" << strerror(pthread_result) << "\")");
+ }
+ }
+ isThreadRunning_ = false;
+ LOG4CXX_TRACE_EXIT(logger_);
+}
+
+std::ostream& operator<<(std::ostream& os, const Thread::Id& thread_id) {
+ return os<<Thread::NameFromId(thread_id);
+}
+
+} // namespace threads
diff --git a/src/components/utils/src/threads/pulse_thread_delegate.cc b/src/components/utils/src/threads/pulse_thread_delegate.cc
new file mode 100644
index 0000000000..8c580bea83
--- /dev/null
+++ b/src/components/utils/src/threads/pulse_thread_delegate.cc
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/netmgr.h>
+
+#include "utils/threads/pulse_thread_delegate.h"
+#include "utils/logger.h"
+
+namespace threads {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+PulseThreadDelegate::PulseThreadDelegate() : run_(false) {
+ LOG4CXX_TRACE(logger_, "Creating QNX channel");
+ chid_ = ChannelCreate(0);
+ if (chid_ == -1) {
+ LOG4CXX_ERROR(logger_, "Failed to create QNX channel");
+ return;
+ }
+ LOG4CXX_DEBUG(logger_, "Created QNX channel " << chid_);
+
+ LOG4CXX_TRACE(logger_, "Connecting to QNX channel " << chid_);
+ coid_ = ConnectAttach(ND_LOCAL_NODE, 0, chid_, _NTO_SIDE_CHANNEL, 0);
+ if (coid_ == -1) {
+ LOG4CXX_ERROR(logger_, "Failed to connect to QNX channel " << chid_);
+ return;
+ }
+ LOG4CXX_DEBUG(logger_, "Connected to QNX channel " << chid_);
+
+ run_ = true;
+}
+
+void PulseThreadDelegate::threadMain() {
+ if (!Init()) {
+ LOG4CXX_ERROR(logger_, "Failed to initialize thread for QNX channel " << chid_);
+ return;
+ }
+ while (run_) {
+ struct sigevent event;
+ SIGEV_PULSE_INIT(&event, coid_, SIGEV_PULSE_PRIO_INHERIT, PULSE_CODE, 0);
+ if (ArmEvent(&event)) {
+ struct _pulse pulse;
+ LOG4CXX_INFO(logger_, "Waiting for pulse on QNX channel " << chid_);
+ if (MsgReceivePulse(chid_, &pulse, sizeof(pulse), 0) != -1) {
+ LOG4CXX_INFO(logger_, "Received pulse on QNX channel " << chid_);
+ switch (pulse.code) {
+ case PULSE_CODE:
+ OnPulse();
+ break;
+ }
+ }
+ else {
+ if (run_) {
+ LOG4CXX_WARN(logger_, "Error occurred while waiting for pulse on QNX channel " << chid_);
+ }
+ else {
+ LOG4CXX_INFO(logger_, "QNX channel " << chid_ << " is apparently destroyed");
+ }
+ }
+ }
+ }
+ Finalize();
+}
+
+bool PulseThreadDelegate::exitThreadMain() {
+ run_ = false;
+
+ LOG4CXX_TRACE(logger_, "Disconnecting from QNX channel " << chid_);
+ if (ConnectDetach(coid_) != -1) {
+ LOG4CXX_DEBUG(logger_, "Disconnected from QNX channel " << chid_);
+ }
+ else {
+ LOG4CXX_WARN(logger_, "Failed to disconnect from QNX channel " << chid_);
+ }
+
+ LOG4CXX_TRACE(logger_, "Destroying QNX channel " << chid_);
+ if (ChannelDestroy(chid_) != -1) { // unblocks MsgReceivePulse()
+ LOG4CXX_DEBUG(logger_, "QNX channel " << chid_ << " destroyed");
+ }
+ else {
+ LOG4CXX_WARN(logger_, "Failed to destroy QNX channel " << chid_);
+ }
+
+ return true;
+}
+
+} // namespace threads
diff --git a/src/components/utils/src/threads/thread_manager.cc b/src/components/utils/src/threads/thread_manager.cc
new file mode 100644
index 0000000000..32a073ad15
--- /dev/null
+++ b/src/components/utils/src/threads/thread_manager.cc
@@ -0,0 +1,115 @@
+/**
+ * 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 "utils/logger.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;
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Utils")
+
+namespace {
+ const char* kUnknownName = "UnnamedThread";
+}
+
+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;
+ }
+ ++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_.find(name) != names_.end()) {
+ LOG4CXX_ERROR(logger_, "Ignoring duplicate thread name: " << name);
+ return;
+ }
+ names_.insert(name);
+ pair<IdNamesMap::iterator, bool> inserted =
+ id_names_.insert(make_pair(id, name));
+ if (!inserted.second) {
+ LOG4CXX_ERROR(logger_, "Trying to register thread name " << name
+ <<", but it is already registered with name "
+ <<inserted.first->second);
+ }
+}
+
+string ThreadManager::GetName(PlatformThreadHandle id) const {
+ AutoLock auto_lock(state_lock_);
+ IdNamesMap::const_iterator found = id_names_.find(id);
+ if (found == id_names_.end()) {
+ LOG4CXX_WARN(logger_, "Thread " << id << " doesn't have associated name");
+ return unnamed_thread_namer_.GetUniqueName(id);
+ }
+ return found->second;
+}
+
+void ThreadManager::Unregister(PlatformThreadHandle id) {
+ AutoLock auto_lock(state_lock_);
+ IdNamesMap::iterator it = id_names_.find(id);
+ if(it != id_names_.end()) {
+ names_.erase(it->second);
+ id_names_.erase(it);
+ }
+}
+
+} // namespace impl
+} // namespace threads
diff --git a/src/components/utils/src/threads/thread_validator.cc b/src/components/utils/src/threads/thread_validator.cc
new file mode 100644
index 0000000000..5e9c88a7c9
--- /dev/null
+++ b/src/components/utils/src/threads/thread_validator.cc
@@ -0,0 +1,92 @@
+/**
+ * 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 {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "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(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(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:
diff --git a/src/components/utils/test/CMakeLists.txt b/src/components/utils/test/CMakeLists.txt
new file mode 100644
index 0000000000..a9ed5acdac
--- /dev/null
+++ b/src/components/utils/test/CMakeLists.txt
@@ -0,0 +1,17 @@
+include_directories (
+ ${CMAKE_SOURCE_DIR}/src/3rd_party-static/gmock-1.7.0/include
+ ${CMAKE_SOURCE_DIR}/src/3rd_party-static/gmock-1.7.0/gtest/include)
+
+set(testSources
+ main.cc
+ file_system_test.cc
+ date_time_test.cc)
+
+set(testLibraries
+ gmock
+ gtest
+ Utils)
+
+add_executable(utils_test ${testSources})
+target_link_libraries(utils_test ${testLibraries})
+
diff --git a/src/components/utils/test/date_time_test.cc b/src/components/utils/test/date_time_test.cc
new file mode 100644
index 0000000000..ddcf679a16
--- /dev/null
+++ b/src/components/utils/test/date_time_test.cc
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2014, Ford Motor Company
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of the Ford Motor Company nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <unistd.h>
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include "utils/date_time.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+TEST(DateTimeTest, GetCurrentTime) {
+ const TimevalStruct time1 = date_time::DateTime::getCurrentTime();
+ ASSERT_NE(0, time1.tv_sec);
+ ASSERT_GE(time1.tv_usec, 0);
+
+ const TimevalStruct time2 = date_time::DateTime::getCurrentTime();
+ ASSERT_NE(0, time2.tv_sec);
+ ASSERT_GE(time2.tv_usec, 0);
+ ASSERT_GE(time2.tv_sec, time1.tv_sec);
+}
+
+TEST(DateTimeTest, GetmSecs) {
+ TimevalStruct time;
+ time.tv_sec = 1;
+ time.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ ASSERT_EQ(time.tv_sec * date_time::DateTime::MILLISECONDS_IN_SECOND +
+ time.tv_usec / date_time::DateTime::MICROSECONDS_IN_MILLISECONDS,
+ date_time::DateTime::getmSecs(time));
+}
+
+TEST(DateTimeTest, GetuSecs) {
+ TimevalStruct time;
+ time.tv_sec = 3;
+ time.tv_usec = 4;
+
+ ASSERT_EQ(time.tv_sec * date_time::DateTime::MILLISECONDS_IN_SECOND *
+ date_time::DateTime::MICROSECONDS_IN_MILLISECONDS + time.tv_usec,
+ date_time::DateTime::getuSecs(time));
+}
+
+TEST(DateTimeTest, GetuSecsmSecs) {
+ TimevalStruct time;
+ time.tv_sec = 5;
+ time.tv_usec = 6;
+
+ ASSERT_EQ( date_time::DateTime::getmSecs(time),
+ date_time::DateTime::getuSecs(time) / date_time::DateTime::MICROSECONDS_IN_MILLISECONDS);
+}
+
+TEST(DateTimeTest, CalculateTimeSpan) {
+ const TimevalStruct time = date_time::DateTime::getCurrentTime();
+
+ const uint32_t sleep_time_mSec = 10;
+ usleep(sleep_time_mSec * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS);
+
+ ASSERT_GE(date_time::DateTime::calculateTimeSpan(time),
+ sleep_time_mSec);
+}
+
+TEST(DateTimeTest, CalculateTimeDiff) {
+ TimevalStruct time1;
+ time1.tv_sec = 1;
+ time1.tv_usec = 2 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ TimevalStruct time2;
+ time2.tv_sec = 3;
+ time2.tv_usec = 4 * date_time::DateTime::MICROSECONDS_IN_MILLISECONDS;
+
+ //time2 to time1
+ TimevalStruct diff1;
+ diff1.tv_sec = time2.tv_sec - time1.tv_sec;
+ diff1.tv_usec = time2.tv_usec - time1.tv_usec;
+
+ const int64_t mSecDiff = static_cast<int64_t>(diff1.tv_sec) * 1000
+ + diff1.tv_usec / 1000;
+
+ ASSERT_EQ(mSecDiff,
+ date_time::DateTime::calculateTimeDiff(time2, time1));
+
+ //time1 to time2
+ TimevalStruct diff2;
+ diff2.tv_sec = time1.tv_sec - time2.tv_sec;
+ diff2.tv_usec = time1.tv_usec - time2.tv_usec;
+
+ const int64_t mSecDiff2 = -(static_cast<int64_t>(diff2.tv_sec) * 1000
+ + diff2.tv_usec / 1000);
+
+ ASSERT_EQ(mSecDiff2,
+ date_time::DateTime::calculateTimeDiff(time1, time2));
+}
+
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/file_system_test.cc b/src/components/utils/test/file_system_test.cc
new file mode 100644
index 0000000000..abf09735ba
--- /dev/null
+++ b/src/components/utils/test/file_system_test.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gmock/gmock.h"
+#include "utils/file_system.h"
+
+namespace test {
+namespace components {
+namespace utils {
+
+TEST(FileSystemTest, CommonFileSystemTest) {
+ // Directory creation
+ ASSERT_FALSE(file_system::DirectoryExists("./Test directory"));
+
+ file_system::CreateDirectory("./Test directory");
+
+ ASSERT_TRUE(file_system::DirectoryExists("./Test directory"));
+
+ ASSERT_TRUE(file_system::IsDirectory("./Test directory"));
+
+ // File creation
+ ASSERT_FALSE(file_system::FileExists("./Test directory/test file"));
+
+ std::vector<unsigned char> data;
+ data.push_back('t');
+ data.push_back('e');
+ data.push_back('s');
+ data.push_back('t');
+
+ ASSERT_TRUE(file_system::Write("./Test directory/test file", data));
+
+ ASSERT_TRUE(file_system::FileExists("./Test directory/test file"));
+
+ ASSERT_FALSE(file_system::IsDirectory("./Test directory/test file"));
+
+ // Read data from file
+ std::vector<unsigned char> result;
+
+ ASSERT_TRUE(file_system::ReadBinaryFile("./Test directory/test file",
+ result));
+ ASSERT_FALSE(result.empty());
+
+ // list files
+ ASSERT_TRUE(file_system::Write("./Test directory/test file 2", data));
+
+ std::vector<std::string> list;
+ list = file_system::ListFiles("./Test directory");
+
+ ASSERT_FALSE(list.empty());
+ std::sort(list.begin(), list.end());
+ ASSERT_EQ("test file", list[0]);
+ ASSERT_EQ("test file 2", list[1]);
+
+ // Delete file
+ ASSERT_TRUE(file_system::FileExists("./Test directory/test file 2"));
+ ASSERT_TRUE(file_system::DeleteFile("./Test directory/test file 2"));
+ ASSERT_FALSE(file_system::FileExists("./Test directory/test file 2"));
+
+ // Delete empty directory
+ file_system::CreateDirectory("./Test directory/Empty directory");
+
+ ASSERT_TRUE(file_system::DirectoryExists(
+ "./Test directory/Empty directory"));
+ ASSERT_TRUE(file_system::RemoveDirectory(
+ "./Test directory/Empty directory", false));
+ ASSERT_FALSE(file_system::DirectoryExists(
+ "./Test directory/Empty directory"));
+
+ ASSERT_FALSE(file_system::RemoveDirectory("./Test directory", false));
+ ASSERT_TRUE(file_system::DirectoryExists("./Test directory"));
+
+ // Delete directory recursively
+ file_system::CreateDirectory("./Test directory/Test directory 2");
+ ASSERT_TRUE(file_system::Write(
+ "./Test directory/Test directory 2/test file 2", data));
+ ASSERT_TRUE(file_system::RemoveDirectory("./Test directory", true));
+
+ ASSERT_FALSE(file_system::DirectoryExists("./Test directory"));
+}
+} // namespace utils
+} // namespace components
+} // namespace test
diff --git a/src/components/utils/test/main.cc b/src/components/utils/test/main.cc
new file mode 100644
index 0000000000..d8242c89a0
--- /dev/null
+++ b/src/components/utils/test/main.cc
@@ -0,0 +1,7 @@
+#include "gmock/gmock.h"
+
+int main(int argc, char** argv) {
+ testing::InitGoogleMock(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+