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 <huangqi3@xiaomi.com>
This commit is contained in:
parent
9dbeaa3b1f
commit
a2941532bd
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user