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