[rtems commit] posix: Rework thread cancellation

Sebastian Huber sebh at rtems.org
Fri May 20 05:59:33 UTC 2016


Module:    rtems
Branch:    master
Commit:    da82656065d09f7b6aa411ba361287afdd787204
Changeset: http://git.rtems.org/rtems/commit/?id=da82656065d09f7b6aa411ba361287afdd787204

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri May 13 10:28:14 2016 +0200

posix: Rework thread cancellation

Add Thread_Life_state::THREAD_LIFE_CHANGE_DEFERRED and rework the POSIX
thread cancellation to use the thread life states.

Update #2555.
Update #2626.

---

 cpukit/posix/Makefile.am                      |  3 +-
 cpukit/posix/include/rtems/posix/cancel.h     | 37 ------------------
 cpukit/posix/include/rtems/posix/threadsup.h  | 33 ----------------
 cpukit/posix/preinstall.am                    |  4 --
 cpukit/posix/src/cancel.c                     | 45 +++++++++++-----------
 cpukit/posix/src/canceleval.c                 | 45 ----------------------
 cpukit/posix/src/pthread.c                    |  7 ----
 cpukit/posix/src/pthreadcreate.c              |  2 +
 cpukit/posix/src/pthreadexit.c                | 29 ++------------
 cpukit/posix/src/pthreadinitthreads.c         |  1 -
 cpukit/posix/src/setcancelstate.c             | 51 +++++++++++--------------
 cpukit/posix/src/setcanceltype.c              | 54 +++++++++++++--------------
 cpukit/posix/src/testcancel.c                 | 36 +++---------------
 cpukit/score/include/rtems/score/thread.h     |  1 +
 cpukit/score/include/rtems/score/threadimpl.h |  9 ++++-
 cpukit/score/src/threadrestart.c              |  6 +--
 16 files changed, 93 insertions(+), 270 deletions(-)

diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am
index d354f7e..a7632a0 100644
--- a/cpukit/posix/Makefile.am
+++ b/cpukit/posix/Makefile.am
@@ -31,7 +31,6 @@ endif
 
 # include/rtems/posix
 include_rtems_posix_HEADERS += include/rtems/posix/aio_misc.h
-include_rtems_posix_HEADERS += include/rtems/posix/cancel.h
 include_rtems_posix_HEADERS += include/rtems/posix/cond.h
 include_rtems_posix_HEADERS += include/rtems/posix/condimpl.h
 include_rtems_posix_HEADERS += include/rtems/posix/mqueue.h
@@ -78,7 +77,7 @@ libposix_a_SOURCES += src/barrierattrdestroy.c src/barrierattrgetpshared.c \
     src/pbarriertranslatereturncode.c src/pbarrierwait.c
 
 ## CANCEL_C_FILES
-libposix_a_SOURCES += src/cancel.c src/canceleval.c \
+libposix_a_SOURCES += src/cancel.c \
     src/cleanuppush.c src/setcancelstate.c \
     src/setcanceltype.c src/testcancel.c
 
diff --git a/cpukit/posix/include/rtems/posix/cancel.h b/cpukit/posix/include/rtems/posix/cancel.h
deleted file mode 100644
index 52bbcbc..0000000
--- a/cpukit/posix/include/rtems/posix/cancel.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @file
- * 
- * @brief POSIX Thread Cancelation Support
- *
- * This file contains the prototypes and data types used to implement
- * POSIX thread cancelation.
- */
-
-/*
- *  COPYRIGHT (c) 1989-2009.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- */
-
-#ifndef _RTEMS_POSIX_CANCEL_H
-#define _RTEMS_POSIX_CANCEL_H
-
-#include <rtems/posix/threadsup.h>
-
-/**
- * @brief POSIX evaluate thread cancelation and enable dispatch. 
- *
- * This routine separates a piece of code that existed as part of
- * another routine, but had to be separated to improve coverage.
- *
- * @param[in] the_thread is a pointer to the thread to evaluate canceling
- */
-void _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch (
-  Thread_Control *the_thread
-);
-
-#endif
-/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h
index 3a7cfbc..51c9564 100644
--- a/cpukit/posix/include/rtems/posix/threadsup.h
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -71,41 +71,8 @@ typedef struct {
    * @brief Signal post-switch action in case signals are pending.
    */
   Thread_Action           Signal_action;
-
-  /*******************************************************************/
-  /*******************************************************************/
-  /***************         POSIX Cancelability         ***************/
-  /*******************************************************************/
-  /*******************************************************************/
-
-  /** This is the cancelability state. */
-  int                     cancelability_state;
-  /** This is the cancelability type. */
-  int                     cancelability_type;
-  /** This indicates if a cancelation has been requested. */
-  int                     cancelation_requested;
 } POSIX_API_Control;
 
-/**
- * @brief POSIX thread exit shared helper.
- *
- * 16.1.5.1 Thread Termination, p1003.1c/Draft 10, p. 150
- *
- * This method is a helper routine which ensures that all
- * POSIX thread calls which result in a thread exiting will
- * do so in the same manner.
- *
- * @param[in] the_thread is a pointer to the thread exiting or being canceled
- * @param[in] value_ptr is a pointer the value to be returned by the thread
- *
- * NOTE: Key destructors are executed in the POSIX api delete extension.
- *
- */
-void _POSIX_Thread_Exit(
-  Thread_Control *the_thread,
-  void           *value_ptr
-);
-
 /** @} */
 
 #ifdef __cplusplus
diff --git a/cpukit/posix/preinstall.am b/cpukit/posix/preinstall.am
index cf1303c..6fc6b4c 100644
--- a/cpukit/posix/preinstall.am
+++ b/cpukit/posix/preinstall.am
@@ -61,10 +61,6 @@ $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h: include/rtems/posix/aio_misc.h $(PROJ
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h
 
-$(PROJECT_INCLUDE)/rtems/posix/cancel.h: include/rtems/posix/cancel.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
-	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cancel.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cancel.h
-
 $(PROJECT_INCLUDE)/rtems/posix/cond.h: include/rtems/posix/cond.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cond.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cond.h
diff --git a/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c
index f103d65..9519c45 100644
--- a/cpukit/posix/src/cancel.c
+++ b/cpukit/posix/src/cancel.c
@@ -9,6 +9,8 @@
  *  COPYRIGHT (c) 1989-2008.
  *  On-Line Applications Research Corporation (OAR).
  *
+ *  Copyright (c) 2016 embedded brains GmbH.
+ *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
  *  http://www.rtems.org/license/LICENSE.
@@ -23,46 +25,43 @@
 
 #include <rtems/score/isr.h>
 #include <rtems/score/threadimpl.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/threadsup.h>
 
 /*
  *  18.2.1 Canceling Execution of a Thread, P1003.1c/Draft 10, p. 181
  */
 
-int pthread_cancel(
-  pthread_t  thread
-)
+int pthread_cancel( pthread_t thread )
 {
-  Thread_Control     *the_thread;
-  POSIX_API_Control  *thread_support;
-  Objects_Locations   location;
+  Thread_Control   *the_thread;
+  ISR_lock_Context  lock_context;
+  Thread_Control   *executing;
+  Per_CPU_Control  *cpu_self;
 
   /*
    *  Don't even think about deleting a resource from an ISR.
    */
 
-  if ( _ISR_Is_in_progress() )
+  if ( _ISR_Is_in_progress() ) {
     return EPROTO;
+  }
 
-  the_thread = _Thread_Get( thread, &location );
-  switch ( location ) {
+  the_thread = _Thread_Get_interrupt_disable( thread, &lock_context );
 
-    case OBJECTS_LOCAL:
-      thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
+  if ( the_thread == NULL ) {
+    return ESRCH;
+  }
 
-      thread_support->cancelation_requested = 1;
+  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+  _ISR_lock_ISR_enable( &lock_context );
 
-      /* This enables dispatch implicitly */
-      _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( the_thread );
-      return 0;
+  executing = _Per_CPU_Get_executing( cpu_self );
 
-#if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:
-#endif
-    case OBJECTS_ERROR:
-      break;
+  if ( the_thread == executing ) {
+    _Thread_Exit( executing, THREAD_LIFE_TERMINATING, PTHREAD_CANCELED );
+  } else {
+    _Thread_Cancel( the_thread, executing, PTHREAD_CANCELED );
   }
 
-  return ESRCH;
+  _Thread_Dispatch_enable( cpu_self );
+  return 0;
 }
diff --git a/cpukit/posix/src/canceleval.c b/cpukit/posix/src/canceleval.c
deleted file mode 100644
index 9e02c92..0000000
--- a/cpukit/posix/src/canceleval.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * @file
- *
- * @brief POSIX Function Evaluates Thread Cancellation and Enables Dispatch
- * @ingroup POSIXAPI
- */
-
-/*
- *  COPYRIGHT (c) 1989-2009.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <pthread.h>
-#include <rtems/system.h>
-#include <rtems/score/thread.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/pthreadimpl.h>
-
-void _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch(
-  Thread_Control    *the_thread
-)
-{
-  POSIX_API_Control *thread_support;
-
-  thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
-
-  if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
-       thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS &&
-       thread_support->cancelation_requested ) {
-    /* FIXME: This path is broken on SMP */
-    _Thread_Unnest_dispatch();
-    /* FIXME: Cancelability state may change here */
-    _POSIX_Thread_Exit( the_thread, PTHREAD_CANCELED );
-  } else
-    _Objects_Put( &the_thread->Object );
-
-}
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 12c5ace..766ac01 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -33,7 +33,6 @@
 #include <rtems/score/userextimpl.h>
 #include <rtems/score/watchdogimpl.h>
 #include <rtems/score/wkspace.h>
-#include <rtems/posix/cancel.h>
 #include <rtems/posix/pthreadimpl.h>
 #include <rtems/posix/priorityimpl.h>
 #include <rtems/posix/psignalimpl.h>
@@ -209,12 +208,6 @@ static bool _POSIX_Threads_Create_extension(
      _POSIX_Priority_From_core( created->current_priority );
 
   /*
-   *  POSIX 1003.1 1996, 18.2.2.2
-   */
-  RTEMS_STATIC_ASSERT( PTHREAD_CANCEL_ENABLE == 0, cancelability_state );
-  RTEMS_STATIC_ASSERT( PTHREAD_CANCEL_DEFERRED == 0, cancelability_type );
-
-  /*
    *  If the thread is not a posix thread, then all posix signals are blocked
    *  by default.
    *
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index 33fae37..7f95898 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -205,6 +205,8 @@ int pthread_create(
     the_thread->Life.state |= THREAD_LIFE_DETACHED;
   }
 
+  the_thread->Life.state |= THREAD_LIFE_CHANGE_DEFERRED;
+
 #if defined(RTEMS_SMP) && __RTEMS_HAVE_SYS_CPUSET_H__
   _ISR_lock_ISR_disable( &lock_context );
    status = _Scheduler_Set_affinity(
diff --git a/cpukit/posix/src/pthreadexit.c b/cpukit/posix/src/pthreadexit.c
index 3c4d3eb..53c42ff 100644
--- a/cpukit/posix/src/pthreadexit.c
+++ b/cpukit/posix/src/pthreadexit.c
@@ -9,6 +9,8 @@
  *  COPYRIGHT (c) 1989-2011.
  *  On-Line Applications Research Corporation (OAR).
  *
+ *  Copyright (c) 2016 embedded brains GmbH.
+ *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
  *  http://www.rtems.org/license/LICENSE.
@@ -20,41 +22,18 @@
 
 #include <pthread.h>
 
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/score/assert.h>
-#include <rtems/score/apimutex.h>
 #include <rtems/score/threadimpl.h>
-#include <rtems/score/threadqimpl.h>
 
-void _POSIX_Thread_Exit(
-  Thread_Control *the_thread,
-  void           *value_ptr
-)
+void pthread_exit( void *value_ptr )
 {
   Thread_Control  *executing;
   Per_CPU_Control *cpu_self;
 
-  _Assert( _Debug_Is_thread_dispatching_allowed() );
-
   cpu_self = _Thread_Dispatch_disable();
   executing = _Per_CPU_Get_executing( cpu_self );
 
-  /*
-   *  Now shut down the thread
-   */
-  if ( the_thread == executing ) {
-    _Thread_Exit( executing, THREAD_LIFE_TERMINATING, value_ptr );
-  } else {
-    _Thread_Cancel( the_thread, executing, value_ptr );
-  }
+  _Thread_Exit( executing, THREAD_LIFE_TERMINATING, value_ptr );
 
   _Thread_Dispatch_enable( cpu_self );
-}
-
-void pthread_exit(
-  void  *value_ptr
-)
-{
-  _POSIX_Thread_Exit( _Thread_Get_executing(), value_ptr );
   RTEMS_UNREACHABLE();
 }
diff --git a/cpukit/posix/src/pthreadinitthreads.c b/cpukit/posix/src/pthreadinitthreads.c
index 05ceda2..ff11e8a 100644
--- a/cpukit/posix/src/pthreadinitthreads.c
+++ b/cpukit/posix/src/pthreadinitthreads.c
@@ -27,7 +27,6 @@
 #include <rtems/score/stack.h>
 #include <rtems/score/thread.h>
 #include <rtems/score/wkspace.h>
-#include <rtems/posix/cancel.h>
 #include <rtems/posix/posixapi.h>
 #include <rtems/posix/pthreadimpl.h>
 #include <rtems/posix/priorityimpl.h>
diff --git a/cpukit/posix/src/setcancelstate.c b/cpukit/posix/src/setcancelstate.c
index a451c2c..b0a42e8 100644
--- a/cpukit/posix/src/setcancelstate.c
+++ b/cpukit/posix/src/setcancelstate.c
@@ -9,6 +9,8 @@
  *  COPYRIGHT (c) 1989-2009.
  *  On-Line Applications Research Corporation (OAR).
  *
+ *  Copyright (c) 2016 embedded brains GmbH.
+ *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
  *  http://www.rtems.org/license/LICENSE.
@@ -21,13 +23,8 @@
 #include <pthread.h>
 #include <errno.h>
 
-#include <rtems/system.h>
-#include <rtems/score/chain.h>
 #include <rtems/score/isr.h>
-#include <rtems/score/thread.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/posix/threadsup.h>
+#include <rtems/score/threadimpl.h>
 
 /*
  *  18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
@@ -38,36 +35,30 @@ int pthread_setcancelstate(
   int *oldstate
 )
 {
-  POSIX_API_Control *thread_support;
-  Thread_Control    *executing;
-
-  /*
-   *  Don't even think about deleting a resource from an ISR.
-   *  Besides this request is supposed to be for _Thread_Executing
-   *  and the ISR context is not a thread.
-   */
+  Thread_Life_state new_life_protection;
+  Thread_Life_state previous_life_state;
 
-  if ( _ISR_Is_in_progress() )
+  if ( _ISR_Is_in_progress() ) {
     return EPROTO;
+  }
 
-  if ( state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE )
+  if ( state == PTHREAD_CANCEL_DISABLE ) {
+    new_life_protection = THREAD_LIFE_PROTECTED;
+  } else if ( state == PTHREAD_CANCEL_ENABLE ) {
+    new_life_protection = 0;
+  } else {
     return EINVAL;
+  }
 
-  _Thread_Disable_dispatch();
-
-    executing = _Thread_Executing;
-    thread_support =  executing ->API_Extensions[ THREAD_API_POSIX ];
-
-    if (oldstate != NULL)
-      *oldstate = thread_support->cancelability_state;
-
-    thread_support->cancelability_state = state;
-
-    _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( executing );
+  previous_life_state = _Thread_Set_life_protection( new_life_protection );
 
-  /*
-   *  _Thread_Enable_dispatch is invoked by above call.
-   */
+  if ( oldstate != NULL ) {
+    if ( ( previous_life_state & THREAD_LIFE_PROTECTED ) != 0 ) {
+      *oldstate = PTHREAD_CANCEL_DISABLE;
+    } else {
+      *oldstate = PTHREAD_CANCEL_ENABLE;
+    }
+  }
 
   return 0;
 }
diff --git a/cpukit/posix/src/setcanceltype.c b/cpukit/posix/src/setcanceltype.c
index 8c4687a..701317f 100644
--- a/cpukit/posix/src/setcanceltype.c
+++ b/cpukit/posix/src/setcanceltype.c
@@ -9,6 +9,8 @@
  *  COPYRIGHT (c) 1989-2009.
  *  On-Line Applications Research Corporation (OAR).
  *
+ *  Copyright (c) 2016 embedded brains GmbH.
+ *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
  *  http://www.rtems.org/license/LICENSE.
@@ -21,13 +23,8 @@
 #include <pthread.h>
 #include <errno.h>
 
-#include <rtems/system.h>
-#include <rtems/score/chain.h>
 #include <rtems/score/isr.h>
-#include <rtems/score/thread.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/posix/threadsup.h>
+#include <rtems/score/threadimpl.h>
 
 /*
  *  18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
@@ -38,35 +35,34 @@ int pthread_setcanceltype(
   int *oldtype
 )
 {
-  POSIX_API_Control *thread_support;
-  Thread_Control    *executing;
-
-  /*
-   *  Don't even think about deleting a resource from an ISR.
-   *  Besides this request is supposed to be for _Thread_Executing
-   *  and the ISR context is not a thread.
-   */
+  Thread_Life_state set_life_state;
+  Thread_Life_state previous_life_state;
 
-  if ( _ISR_Is_in_progress() )
+  if ( _ISR_Is_in_progress() ) {
     return EPROTO;
+  }
 
-  if ( type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS )
+  if ( type == PTHREAD_CANCEL_DEFERRED ) {
+    set_life_state = THREAD_LIFE_CHANGE_DEFERRED;
+  } else if ( type == PTHREAD_CANCEL_ASYNCHRONOUS ) {
+    set_life_state = 0;
+  } else {
     return EINVAL;
+  }
 
-  _Thread_Disable_dispatch();
-
-    executing = _Thread_Executing;
-    thread_support =  executing ->API_Extensions[ THREAD_API_POSIX ];
-
-    if ( oldtype != NULL )
-      *oldtype = thread_support->cancelability_type;
-
-    thread_support->cancelability_type = type;
+  previous_life_state = _Thread_Change_life(
+    THREAD_LIFE_CHANGE_DEFERRED,
+    set_life_state,
+    0
+  );
 
-    _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( executing );
+  if ( oldtype != NULL ) {
+    if ( ( previous_life_state & THREAD_LIFE_CHANGE_DEFERRED ) != 0 ) {
+      *oldtype = PTHREAD_CANCEL_DEFERRED;
+    } else {
+      *oldtype = PTHREAD_CANCEL_ASYNCHRONOUS;
+    }
+  }
 
-  /*
-   *  _Thread_Enable_dispatch is invoked by above call.
-   */
   return 0;
 }
diff --git a/cpukit/posix/src/testcancel.c b/cpukit/posix/src/testcancel.c
index c78f26a..f50c778 100644
--- a/cpukit/posix/src/testcancel.c
+++ b/cpukit/posix/src/testcancel.c
@@ -9,6 +9,8 @@
  *  COPYRIGHT (c) 1989-2008.
  *  On-Line Applications Research Corporation (OAR).
  *
+ *  Copyright (c) 2016 embedded brains GmbH.
+ *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
  *  http://www.rtems.org/license/LICENSE.
@@ -19,16 +21,9 @@
 #endif
 
 #include <pthread.h>
-#include <errno.h>
 
-#include <rtems/system.h>
-#include <rtems/score/chain.h>
 #include <rtems/score/isr.h>
-#include <rtems/score/thread.h>
-#include <rtems/score/wkspace.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/posix/threadsup.h>
+#include <rtems/score/threadimpl.h>
 
 /*
  *  18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
@@ -36,28 +31,9 @@
 
 void pthread_testcancel( void )
 {
-  POSIX_API_Control *thread_support;
-  Thread_Control    *executing;
-  bool               cancel = false;
-
-  /*
-   *  Don't even think about deleting a resource from an ISR.
-   *  Besides this request is supposed to be for _Thread_Executing
-   *  and the ISR context is not a thread.
-   */
-
-  if ( _ISR_Is_in_progress() )
+  if ( _ISR_Is_in_progress() ) {
     return;
+  }
 
-  _Thread_Disable_dispatch();
-    executing = _Thread_Executing;
-    thread_support = executing->API_Extensions[ THREAD_API_POSIX ];
-
-    if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
-         thread_support->cancelation_requested )
-      cancel = true;
-  _Thread_Enable_dispatch();
-
-  if ( cancel )
-    _POSIX_Thread_Exit( executing, PTHREAD_CANCELED );
+  _Thread_Change_life( 0, 0, THREAD_LIFE_CHANGE_DEFERRED );
 }
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 352fb2e..8672fdd 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -526,6 +526,7 @@ typedef enum {
   THREAD_LIFE_PROTECTED = 0x1,
   THREAD_LIFE_RESTARTING = 0x2,
   THREAD_LIFE_TERMINATING = 0x4,
+  THREAD_LIFE_CHANGE_DEFERRED = 0x8,
   THREAD_LIFE_DETACHED = 0x10
 } Thread_Life_state;
 
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 6f97ca9..549ca7a 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -205,6 +205,12 @@ bool _Thread_Restart_other(
 
 void _Thread_Yield( Thread_Control *executing );
 
+Thread_Life_state _Thread_Change_life(
+  Thread_Life_state clear,
+  Thread_Life_state set,
+  Thread_Life_state ignore
+);
+
 Thread_Life_state _Thread_Set_life_protection( Thread_Life_state state );
 
 /**
@@ -933,7 +939,8 @@ RTEMS_INLINE_ROUTINE bool _Thread_Is_life_change_allowed(
   Thread_Life_state life_state
 )
 {
-  return ( life_state & THREAD_LIFE_PROTECTED ) == 0;
+  return ( life_state
+    & ( THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED ) ) == 0;
 }
 
 RTEMS_INLINE_ROUTINE bool _Thread_Is_life_changing(
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index fbda7ad..33c56e0 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -558,7 +558,7 @@ void _Thread_Exit(
     executing,
     0,
     set,
-    THREAD_LIFE_PROTECTED
+    THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED
   );
   _Thread_State_release( executing, &lock_context );
 }
@@ -630,7 +630,7 @@ void _Thread_Restart_self(
     executing,
     0,
     THREAD_LIFE_RESTARTING,
-    THREAD_LIFE_PROTECTED
+    THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED
   );
 
   cpu_self = _Thread_Dispatch_disable_critical( lock_context );
@@ -647,7 +647,7 @@ void _Thread_Restart_self(
   RTEMS_UNREACHABLE();
 }
 
-static Thread_Life_state _Thread_Change_life(
+Thread_Life_state _Thread_Change_life(
   Thread_Life_state clear,
   Thread_Life_state set,
   Thread_Life_state ignore



More information about the vc mailing list