You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2021/05/22 04:47:12 UTC

[incubator-nuttx] 09/09: pthread: Avoid recursive pthread_exit call

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit a2941532bdacba9b8e69dfae4b365aff33f0503a
Author: Huang Qi <hu...@xiaomi.com>
AuthorDate: Mon May 17 17:31:13 2021 +0800

    pthread: Avoid recursive pthread_exit call
    
    pthread_exit will be called recursive when pthread_cancel
    or other cleanup operation with syscalls that support
    cancellation, to avoid this by mark current tcb flag as
    TCB_FLAG_CANCEL_DOING instead of TCB_FLAG_CANCEL_PENDING.
    
    Signed-off-by: Huang Qi <hu...@xiaomi.com>
---
 sched/pthread/pthread_cancel.c   |  3 +--
 sched/signal/sig_default.c       |  3 +--
 sched/task/task_cancelpt.c       |  6 ++----
 sched/task/task_setcancelstate.c |  3 +--
 sched/task/task_setcanceltype.c  | 11 +++++------
 5 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/sched/pthread/pthread_cancel.c b/sched/pthread/pthread_cancel.c
index e4088ba..adc2b7e 100644
--- a/sched/pthread/pthread_cancel.c
+++ b/sched/pthread/pthread_cancel.c
@@ -84,10 +84,9 @@ int pthread_cancel(pthread_t thread)
 
   if (tcb == this_task())
     {
-#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
       tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
       tcb->flags |= TCB_FLAG_CANCEL_DOING;
-
+#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
       up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
                       PTHREAD_CANCELED);
 #else
diff --git a/sched/signal/sig_default.c b/sched/signal/sig_default.c
index 7e87089..0078f47 100644
--- a/sched/signal/sig_default.c
+++ b/sched/signal/sig_default.c
@@ -224,10 +224,9 @@ static void nxsig_abnormal_termination(int signo)
        * REVISIT:  This will not work if HAVE_GROUP_MEMBERS is not set.
        */
 
-#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
       rtcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
       rtcb->flags |= TCB_FLAG_CANCEL_DOING;
-
+#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
       up_pthread_exit(((FAR struct pthread_tcb_s *)rtcb)->exit,
                                   PTHREAD_CANCELED);
 #else
diff --git a/sched/task/task_cancelpt.c b/sched/task/task_cancelpt.c
index 659e5db..228e90e 100644
--- a/sched/task/task_cancelpt.c
+++ b/sched/task/task_cancelpt.c
@@ -140,10 +140,9 @@ bool enter_cancellation_point(void)
               if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
                   TCB_FLAG_TTYPE_PTHREAD)
                 {
-#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
                   tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
                   tcb->flags |= TCB_FLAG_CANCEL_DOING;
-
+#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
                   up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
                                   PTHREAD_CANCELED);
 #else
@@ -235,10 +234,9 @@ void leave_cancellation_point(void)
               if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
                   TCB_FLAG_TTYPE_PTHREAD)
                 {
-#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
                   tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
                   tcb->flags |= TCB_FLAG_CANCEL_DOING;
-
+#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
                   up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
                                   PTHREAD_CANCELED);
 #else
diff --git a/sched/task/task_setcancelstate.c b/sched/task/task_setcancelstate.c
index 6b61632..63f3ef3 100644
--- a/sched/task/task_setcancelstate.c
+++ b/sched/task/task_setcancelstate.c
@@ -112,10 +112,9 @@ int task_setcancelstate(int state, FAR int *oldstate)
               if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
                   TCB_FLAG_TTYPE_PTHREAD)
                 {
-#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
                   tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
                   tcb->flags |= TCB_FLAG_CANCEL_DOING;
-
+#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
                   up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
                                   PTHREAD_CANCELED);
 #else
diff --git a/sched/task/task_setcanceltype.c b/sched/task/task_setcanceltype.c
index d57cc64..f33aeb1 100644
--- a/sched/task/task_setcanceltype.c
+++ b/sched/task/task_setcanceltype.c
@@ -100,14 +100,13 @@ int task_setcanceltype(int type, FAR int *oldtype)
 #ifndef CONFIG_DISABLE_PTHREAD
           if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
             {
+              tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
+              tcb->flags |= TCB_FLAG_CANCEL_DOING;
 #if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
-                  tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
-                  tcb->flags |= TCB_FLAG_CANCEL_DOING;
-
-                  up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
-                                  PTHREAD_CANCELED);
+              up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
+                               PTHREAD_CANCELED);
 #else
-                  pthread_exit(PTHREAD_CANCELED);
+              pthread_exit(PTHREAD_CANCELED);
 #endif
             }
           else