diff options
Diffstat (limited to 'include/distortos/internal/memory/DeferredThreadDeleter.hpp')
-rw-r--r-- | include/distortos/internal/memory/DeferredThreadDeleter.hpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/include/distortos/internal/memory/DeferredThreadDeleter.hpp b/include/distortos/internal/memory/DeferredThreadDeleter.hpp new file mode 100644 index 0000000..bb38ebc --- /dev/null +++ b/include/distortos/internal/memory/DeferredThreadDeleter.hpp @@ -0,0 +1,121 @@ +/** + * \file + * \brief DeferredThreadDeleter class header + * + * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info + * + * \par License + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not + * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDE_DISTORTOS_INTERNAL_MEMORY_DEFERREDTHREADDELETER_HPP_ +#define INCLUDE_DISTORTOS_INTERNAL_MEMORY_DEFERREDTHREADDELETER_HPP_ + +#include "distortos/distortosConfiguration.h" + +#ifdef CONFIG_THREAD_DETACH_ENABLE + +#include "distortos/Mutex.hpp" + +namespace distortos +{ + +namespace internal +{ + +/// DeferredThreadDeleter class can be used to defer deletion of dynamic detached threads +class DeferredThreadDeleter +{ +public: + + /** + * \brief DeferredThreadDeleter's constructor + */ + + constexpr DeferredThreadDeleter() : + list_{}, + mutex_{Mutex::Type::normal, Mutex::Protocol::priorityInheritance}, + notEmpty_{} + { + + } + + /** + * \brief DeferredThreadDeleter's function call operator + * + * Adds thread to internal list of threads scheduled for deferred deletion and marks the list as "not empty". + * + * \note The object must be locked (with a successful call to DeferredThreadDeleter::lock()) before this function is + * used! + * + * \param [in] threadControlBlock is a reference to ThreadControlBlock object associated with dynamic and detached + * thread that has terminated its execution + * + * \return 0 on success, error code otherwise: + * - error codes returned by Mutex::unlock(); + */ + + int operator()(ThreadControlBlock& threadControlBlock); + + /** + * \brief Locks the object, preparing it for adding thread to internal list. + * + * Locks the mutex that synchronizes access to internal list. Locking (performed in this function) and unlocking + * (performed at the end of function call operator) are separated, because the locking must be done while the thread + * is still runnable, while the transfer to internal list is performed when the thread is not in this state. + * + * \note This function must be called before function call operator is used! + * + * \return 0 on success, error code otherwise: + * - error codes returned by Mutex::lock(); + */ + + int lock(); + + /** + * \brief Tries to perform deferred deletion of threads. + * + * Does nothing is the list is not marked as "not empty". Otherwise this function first tries to lock following two + * mutexes: + * - mutex that protects dynamic memory allocator; + * - mutex that synchronizes access to list of threads scheduled for deferred deletion; + * If any Mutex::tryLock() call fails, this function just returns (unlocking any mutexes is necessary). Otherwise + * the threads are removed from the list and deleted, while the list's "not empty" marker is cleared. + * + * \return 0 on success, error code otherwise: + * - error codes returned by Mutex::tryLock(); + * - error codes returned by Mutex::unlock(); + */ + + int tryCleanup(); + +private: + + /** + * \brief Internals of tryCleanup(). + * + * \return 0 on success, error code otherwise: + * - error codes returned by Mutex::tryLock(); + * - error codes returned by Mutex::unlock(); + */ + + int tryCleanupInternal(); + + /// list of threads scheduled for deferred deletion + ThreadList::UnsortedIntrusiveList list_; + + /// mutex that synchronizes access to the \a list_ + Mutex mutex_; + + /// true if \a list_ is not empty, false otherwise + bool notEmpty_; +}; + +} // namespace internal + +} // namespace distortos + +#endif // def CONFIG_THREAD_DETACH_ENABLE + +#endif // INCLUDE_DISTORTOS_INTERNAL_MEMORY_DEFERREDTHREADDELETER_HPP_ |