aboutsummaryrefslogtreecommitdiffstats
path: root/include/distortos/internal/memory/DeferredThreadDeleter.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/distortos/internal/memory/DeferredThreadDeleter.hpp')
-rw-r--r--include/distortos/internal/memory/DeferredThreadDeleter.hpp121
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_