<div dir="ltr">Is there a test case for this situation?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, May 20, 2021 at 10:18 AM Sebastian Huber <<a href="mailto:sebastian.huber@embedded-brains.de">sebastian.huber@embedded-brains.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The _Thread_Cancel() (in contrast to _Thread_Restart() which used a<br>
similar code block) may have produced ready threads with an active timer<br>
in case the thread to cancel had its thread life protection enabled. The<br>
problem was this code block:<br>
<br>
    Priority_Control priority;<br>
<br>
    _Thread_Add_life_change_request( the_thread );<br>
<br>
    if ( _Thread_Is_life_change_allowed( previous ) ) {<br>
      _Thread_State_release( the_thread, &lock_context );<br>
<br>
      _Thread_queue_Extract_with_proxy( the_thread );<br>
      _Thread_Timer_remove( the_thread );<br>
    } else {<br>
      _Thread_Clear_state_locked( the_thread, STATES_SUSPENDED );<br>
      _Thread_State_release( the_thread, &lock_context );<br>
    }<br>
<br>
    priority = _Thread_Get_priority( executing );<br>
    _Thread_Raise_real_priority( the_thread, priority );<br>
    _Thread_Remove_life_change_request( the_thread );<br>
<br>
The life change request should only be added/removed if a life change is<br>
allowed (see _Thread_Restart()).  Add<br>
_Thread_Consider_life_change_request() and use it in _Thread_Cancel()<br>
and _Thread_Restart().<br>
<br>
Close #4435.<br>
---<br>
 cpukit/score/src/threadrestart.c | 50 ++++++++++++++++----------------<br>
 1 file changed, 25 insertions(+), 25 deletions(-)<br>
<br>
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c<br>
index 933faee61b..58fcd89159 100644<br>
--- a/cpukit/score/src/threadrestart.c<br>
+++ b/cpukit/score/src/threadrestart.c<br>
@@ -403,6 +403,25 @@ static void _Thread_Set_exit_value(<br>
   the_thread->Life.exit_value = exit_value;<br>
 }<br>
<br>
+static void _Thread_Consider_life_change_request(<br>
+  Thread_Control    *the_thread,<br>
+  Thread_Life_state  previous,<br>
+  ISR_lock_Context  *lock_context<br>
+)<br>
+{<br>
+  if ( _Thread_Is_life_change_allowed( previous ) ) {<br>
+    _Thread_Add_life_change_request( the_thread );<br>
+    _Thread_State_release( the_thread, lock_context );<br>
+<br>
+    _Thread_queue_Extract_with_proxy( the_thread );<br>
+    _Thread_Timer_remove( the_thread );<br>
+    _Thread_Remove_life_change_request( the_thread );<br>
+  } else {<br>
+    _Thread_Clear_state_locked( the_thread, STATES_SUSPENDED );<br>
+    _Thread_State_release( the_thread, lock_context );<br>
+  }<br>
+}<br>
+<br>
 void _Thread_Cancel(<br>
   Thread_Control *the_thread,<br>
   Thread_Control *executing,<br>
@@ -433,21 +452,13 @@ void _Thread_Cancel(<br>
   } else {<br>
     Priority_Control priority;<br>
<br>
-    _Thread_Add_life_change_request( the_thread );<br>
-<br>
-    if ( _Thread_Is_life_change_allowed( previous ) ) {<br>
-      _Thread_State_release( the_thread, &lock_context );<br>
-<br>
-      _Thread_queue_Extract_with_proxy( the_thread );<br>
-      _Thread_Timer_remove( the_thread );<br>
-    } else {<br>
-      _Thread_Clear_state_locked( the_thread, STATES_SUSPENDED );<br>
-      _Thread_State_release( the_thread, &lock_context );<br>
-    }<br>
-<br>
+    _Thread_Consider_life_change_request(<br>
+      the_thread,<br>
+      previous,<br>
+      &lock_context<br>
+    );<br>
     priority = _Thread_Get_priority( executing );<br>
     _Thread_Raise_real_priority( the_thread, priority );<br>
-    _Thread_Remove_life_change_request( the_thread );<br>
   }<br>
<br>
   _Thread_Dispatch_enable( cpu_self );<br>
@@ -559,18 +570,7 @@ Status_Control _Thread_Restart(<br>
     THREAD_LIFE_RESTARTING,<br>
     ignored_life_states<br>
   );<br>
-<br>
-  if ( _Thread_Is_life_change_allowed( previous ) ) {<br>
-    _Thread_Add_life_change_request( the_thread );<br>
-    _Thread_State_release( the_thread, lock_context );<br>
-<br>
-    _Thread_queue_Extract_with_proxy( the_thread );<br>
-    _Thread_Timer_remove( the_thread );<br>
-    _Thread_Remove_life_change_request( the_thread );<br>
-  } else {<br>
-    _Thread_Clear_state_locked( the_thread, STATES_SUSPENDED );<br>
-    _Thread_State_release( the_thread, lock_context );<br>
-  }<br>
+  _Thread_Consider_life_change_request( the_thread, previous, lock_context );<br>
<br>
   _Thread_queue_Context_initialize( &queue_context );<br>
   _Thread_queue_Context_clear_priority_updates( &queue_context );<br>
-- <br>
2.26.2<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</blockquote></div>