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 (tcb == this_task())
|
||||||
{
|
{
|
||||||
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
|
||||||
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
||||||
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
||||||
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
||||||
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
||||||
PTHREAD_CANCELED);
|
PTHREAD_CANCELED);
|
||||||
#else
|
#else
|
||||||
|
@ -224,10 +224,9 @@ static void nxsig_abnormal_termination(int signo)
|
|||||||
* REVISIT: This will not work if HAVE_GROUP_MEMBERS is not set.
|
* 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_PENDING;
|
||||||
rtcb->flags |= TCB_FLAG_CANCEL_DOING;
|
rtcb->flags |= TCB_FLAG_CANCEL_DOING;
|
||||||
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
||||||
up_pthread_exit(((FAR struct pthread_tcb_s *)rtcb)->exit,
|
up_pthread_exit(((FAR struct pthread_tcb_s *)rtcb)->exit,
|
||||||
PTHREAD_CANCELED);
|
PTHREAD_CANCELED);
|
||||||
#else
|
#else
|
||||||
|
@ -140,10 +140,9 @@ bool enter_cancellation_point(void)
|
|||||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
|
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
|
||||||
TCB_FLAG_TTYPE_PTHREAD)
|
TCB_FLAG_TTYPE_PTHREAD)
|
||||||
{
|
{
|
||||||
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
|
||||||
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
||||||
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
||||||
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
||||||
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
||||||
PTHREAD_CANCELED);
|
PTHREAD_CANCELED);
|
||||||
#else
|
#else
|
||||||
@ -235,10 +234,9 @@ void leave_cancellation_point(void)
|
|||||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
|
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
|
||||||
TCB_FLAG_TTYPE_PTHREAD)
|
TCB_FLAG_TTYPE_PTHREAD)
|
||||||
{
|
{
|
||||||
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
|
||||||
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
||||||
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
||||||
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
||||||
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
||||||
PTHREAD_CANCELED);
|
PTHREAD_CANCELED);
|
||||||
#else
|
#else
|
||||||
|
@ -112,10 +112,9 @@ int task_setcancelstate(int state, FAR int *oldstate)
|
|||||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
|
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
|
||||||
TCB_FLAG_TTYPE_PTHREAD)
|
TCB_FLAG_TTYPE_PTHREAD)
|
||||||
{
|
{
|
||||||
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
|
||||||
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
||||||
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
||||||
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
||||||
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
||||||
PTHREAD_CANCELED);
|
PTHREAD_CANCELED);
|
||||||
#else
|
#else
|
||||||
|
@ -100,14 +100,13 @@ int task_setcanceltype(int type, FAR int *oldtype)
|
|||||||
#ifndef CONFIG_DISABLE_PTHREAD
|
#ifndef CONFIG_DISABLE_PTHREAD
|
||||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_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__)
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
||||||
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
||||||
tcb->flags |= TCB_FLAG_CANCEL_DOING;
|
PTHREAD_CANCELED);
|
||||||
|
|
||||||
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
|
|
||||||
PTHREAD_CANCELED);
|
|
||||||
#else
|
#else
|
||||||
pthread_exit(PTHREAD_CANCELED);
|
pthread_exit(PTHREAD_CANCELED);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user