From edc473a526c22cf745c99f40926e952d2f00c489 Mon Sep 17 00:00:00 2001 From: Russ Butler Date: Wed, 1 Mar 2017 14:37:55 -0600 Subject: [PATCH] rtos: Return an error when a Thread is re-used Calling Thread::start multiple times leads to undefined behavior since the Thread class was not designed to handle being restarted. Return an error code if Thread::start is called a second time to prevent this behavior. --- rtos/Thread.cpp | 5 ++++- rtos/Thread.h | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/rtos/Thread.cpp b/rtos/Thread.cpp index 61bfe964c6..c168afde2f 100644 --- a/rtos/Thread.cpp +++ b/rtos/Thread.cpp @@ -44,6 +44,7 @@ namespace rtos { void Thread::constructor(osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) { _tid = 0; + _finished = false; _dynamic_stack = (stack_pointer == NULL); #if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) @@ -74,7 +75,7 @@ void Thread::constructor(Callback task, osStatus Thread::start(Callback task) { _mutex.lock(); - if (_tid != 0) { + if ((_tid != 0) || _finished) { _mutex.unlock(); return osErrorParameter; } @@ -117,6 +118,7 @@ osStatus Thread::terminate() { osThreadId local_id = _tid; _join_sem.release(); _tid = (osThreadId)NULL; + _finished = true; ret = osThreadTerminate(local_id); @@ -367,6 +369,7 @@ void Thread::_thunk(const void * thread_ptr) t->_task(); t->_mutex.lock(); t->_tid = (osThreadId)NULL; + t->_finished = true; t->_join_sem.release(); // rtos will release the mutex automatically } diff --git a/rtos/Thread.h b/rtos/Thread.h index 6c480d74b7..1df34c3712 100644 --- a/rtos/Thread.h +++ b/rtos/Thread.h @@ -197,6 +197,7 @@ public: /** Starts a thread executing the specified function. @param task function to be executed by this thread. @return status code that indicates the execution status of the function. + @note a thread can only be started once */ osStatus start(mbed::Callback task); @@ -344,9 +345,10 @@ private: mbed::Callback _task; osThreadId _tid; osThreadDef_t _thread_def; - bool _dynamic_stack; Semaphore _join_sem; Mutex _mutex; + bool _dynamic_stack; + bool _finished; }; }