summaryrefslogtreecommitdiff
path: root/components/libc/pthreads/pthread.c
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2018-02-07 19:55:26 +0800
committerBernard Xiong <[email protected]>2018-02-07 19:55:35 +0800
commit84a44e58ddcd57d12c3a1dcbff17ff9d96b2cd41 (patch)
tree83d42be305ca92497e4250435b5c54997c004a62 /components/libc/pthreads/pthread.c
parent55e2fabbc5a180e3bf3a3f287cd6b5cc81d2fd24 (diff)
[pthread] Fix pthread_detach issue for a none-joinable thread
Diffstat (limited to 'components/libc/pthreads/pthread.c')
-rw-r--r--components/libc/pthreads/pthread.c78
1 files changed, 50 insertions, 28 deletions
diff --git a/components/libc/pthreads/pthread.c b/components/libc/pthreads/pthread.c
index 12ec1d7647..103b5de33d 100644
--- a/components/libc/pthreads/pthread.c
+++ b/components/libc/pthreads/pthread.c
@@ -1,7 +1,7 @@
/*
* File : pthread.c
* This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2012, RT-Thread Development Team
+ * COPYRIGHT (C) 2012 - 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,8 @@
*
* Change Logs:
* Date Author Notes
+ * 2018-01-26 Bernard Fix pthread_detach issue for a none-joinable
+ * thread.
*/
#include <pthread.h>
@@ -61,7 +63,7 @@ static void pthread_entry_stub(void *parameter)
_pthread_data_t *ptd;
void *value;
- ptd = (_pthread_data_t*)parameter;
+ ptd = (_pthread_data_t *)parameter;
/* execute pthread entry */
value = ptd->thread_entry(ptd->thread_parameter);
@@ -70,8 +72,8 @@ static void pthread_entry_stub(void *parameter)
}
int pthread_create(pthread_t *tid,
- const pthread_attr_t *attr,
- void *(*start) (void *), void *parameter)
+ const pthread_attr_t *attr,
+ void *(*start)(void *), void *parameter)
{
int result;
void *stack;
@@ -83,7 +85,7 @@ int pthread_create(pthread_t *tid,
RT_ASSERT(tid != RT_NULL);
/* allocate posix thread data */
- ptd = (_pthread_data_t*)rt_malloc(sizeof(_pthread_data_t));
+ ptd = (_pthread_data_t *)rt_malloc(sizeof(_pthread_data_t));
if (ptd == RT_NULL)
return ENOMEM;
/* clean posix thread data memory */
@@ -94,8 +96,10 @@ int pthread_create(pthread_t *tid,
ptd->magic = PTHREAD_MAGIC;
if (attr != RT_NULL)
+ {
ptd->attr = *attr;
- else
+ }
+ else
{
/* use default attribute */
pthread_attr_init(&ptd->attr);
@@ -104,12 +108,14 @@ int pthread_create(pthread_t *tid,
rt_snprintf(name, sizeof(name), "pth%02d", pthread_number ++);
if (ptd->attr.stack_base == 0)
{
- stack = (void*)rt_malloc(ptd->attr.stack_size);
+ stack = (void *)rt_malloc(ptd->attr.stack_size);
}
else
- stack = (void*)(ptd->attr.stack_base);
+ {
+ stack = (void *)(ptd->attr.stack_base);
+ }
- if (stack == RT_NULL)
+ if (stack == RT_NULL)
{
rt_free(ptd);
@@ -140,16 +146,18 @@ int pthread_create(pthread_t *tid,
}
}
else
+ {
ptd->joinable_sem = RT_NULL;
+ }
/* set parameter */
ptd->thread_entry = start;
ptd->thread_parameter = parameter;
/* initial this pthread to system */
- if (rt_thread_init(ptd->tid, name, pthread_entry_stub, ptd,
- stack, ptd->attr.stack_size,
- ptd->attr.priority, 5) != RT_EOK)
+ if (rt_thread_init(ptd->tid, name, pthread_entry_stub, ptd,
+ stack, ptd->attr.stack_size,
+ ptd->attr.priority, 5) != RT_EOK)
{
if (ptd->attr.stack_base == 0)
rt_free(stack);
@@ -187,11 +195,19 @@ RTM_EXPORT(pthread_create);
int pthread_detach(pthread_t thread)
{
- _pthread_data_t* ptd;
+ _pthread_data_t *ptd;
ptd = _pthread_get_data(thread);
- if ((thread->stat & RT_THREAD_STAT_MASK)== RT_THREAD_CLOSE)
+ if (ptd->attr.detachstate == PTHREAD_CREATE_DETACHED)
+ {
+ /* The implementation has detected that the value specified by thread does not refer
+ * to a joinable thread.
+ */
+ return EINVAL;
+ }
+
+ if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
{
/* delete joinable semaphore */
if (ptd->joinable_sem != RT_NULL)
@@ -205,6 +221,11 @@ int pthread_detach(pthread_t thread)
/* release thread allocated stack */
rt_free(ptd->tid->stack_addr);
}
+ else
+ {
+ /* clean stack addr pointer */
+ ptd->tid->stack_addr = RT_NULL;
+ }
/*
* if this thread create the local thread data,
@@ -231,9 +252,9 @@ int pthread_detach(pthread_t thread)
}
RTM_EXPORT(pthread_detach);
-int pthread_join (pthread_t thread, void **value_ptr)
+int pthread_join(pthread_t thread, void **value_ptr)
{
- _pthread_data_t* ptd;
+ _pthread_data_t *ptd;
rt_err_t result;
if (thread == rt_thread_self())
@@ -257,13 +278,15 @@ int pthread_join (pthread_t thread, void **value_ptr)
pthread_detach(thread);
}
else
+ {
return ESRCH;
-
+ }
+
return 0;
}
RTM_EXPORT(pthread_join);
-void pthread_exit (void *value)
+void pthread_exit(void *value)
{
_pthread_data_t *ptd;
_pthread_cleanup_t *cleanup;
@@ -294,7 +317,7 @@ void pthread_exit (void *value)
{
void *data;
rt_uint32_t index;
-
+
for (index = 0; index < PTHREAD_KEY_MAX; index ++)
{
if (_thread_keys[index].is_used)
@@ -323,7 +346,7 @@ void pthread_exit (void *value)
}
RTM_EXPORT(pthread_exit);
-int pthread_once(pthread_once_t *once_control, void (*init_routine) (void))
+int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
{
RT_ASSERT(once_control != RT_NULL);
RT_ASSERT(init_routine != RT_NULL);
@@ -354,7 +377,7 @@ int pthread_kill(pthread_t thread, int sig)
#ifdef RT_USING_SIGNALS
return rt_thread_kill(thread, sig);
#else
- return ENOSYS;
+ return ENOSYS;
#endif
}
RTM_EXPORT(pthread_kill);
@@ -362,7 +385,7 @@ RTM_EXPORT(pthread_kill);
#ifdef RT_USING_SIGNALS
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
{
- return sigprocmask(how, set, oset);
+ return sigprocmask(how, set, oset);
}
#endif
@@ -393,7 +416,7 @@ void pthread_cleanup_pop(int execute)
}
RTM_EXPORT(pthread_cleanup_pop);
-void pthread_cleanup_push(void (*routine)(void*), void *arg)
+void pthread_cleanup_push(void (*routine)(void *), void *arg)
{
_pthread_data_t *ptd;
_pthread_cleanup_t *cleanup;
@@ -473,7 +496,7 @@ int pthread_setcanceltype(int type, int *oldtype)
ptd = _pthread_get_data(rt_thread_self());
RT_ASSERT(ptd != RT_NULL);
- if ((type != PTHREAD_CANCEL_DEFERRED) && (type != PTHREAD_CANCEL_ASYNCHRONOUS))
+ if ((type != PTHREAD_CANCEL_DEFERRED) && (type != PTHREAD_CANCEL_ASYNCHRONOUS))
return EINVAL;
if (oldtype)
@@ -486,8 +509,8 @@ RTM_EXPORT(pthread_setcanceltype);
void pthread_testcancel(void)
{
- int cancel=0;
- _pthread_data_t* ptd;
+ int cancel = 0;
+ _pthread_data_t *ptd;
/* get posix thread data */
ptd = _pthread_get_data(rt_thread_self());
@@ -496,7 +519,7 @@ void pthread_testcancel(void)
if (ptd->cancelstate == PTHREAD_CANCEL_ENABLE)
cancel = ptd->canceled;
if (cancel)
- pthread_exit((void*)PTHREAD_CANCELED);
+ pthread_exit((void *)PTHREAD_CANCELED);
}
RTM_EXPORT(pthread_testcancel);
@@ -532,4 +555,3 @@ int pthread_cancel(pthread_t thread)
return 0;
}
RTM_EXPORT(pthread_cancel);
-