mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
2011-07-31 Joel Sherrill <joel.sherrilL@OARcorp.com>
PR 1867/cpukit * posix/src/pthreadexit.c, posix/src/pthreadjoin.c: Correct implementation of pthread_exit() and pthread_join() to support the case where a thread is joinable but calls pthread_exit() before a thread has attempted to join.
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
2011-07-31 Joel Sherrill <joel.sherrilL@OARcorp.com>
|
||||
|
||||
PR 1867/cpukit
|
||||
* posix/src/pthreadexit.c, posix/src/pthreadjoin.c: Correct
|
||||
implementation of pthread_exit() and pthread_join() to support the
|
||||
case where a thread is joinable but calls pthread_exit() before a
|
||||
thread has attempted to join.
|
||||
|
||||
2011-07-31 Joel Sherrill <joel.sherrilL@OARcorp.com>
|
||||
|
||||
PR 1839/filesystem
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* NOTE: Key destructors are executed in the POSIX api delete extension.
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2008.
|
||||
* COPYRIGHT (c) 1989-2011.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
@@ -25,15 +25,21 @@
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/posix/pthread.h>
|
||||
|
||||
|
||||
void _POSIX_Thread_Exit(
|
||||
Thread_Control *the_thread,
|
||||
void *value_ptr
|
||||
)
|
||||
{
|
||||
Objects_Information *the_information;
|
||||
Objects_Information *the_information;
|
||||
Thread_Control *unblocked;
|
||||
POSIX_API_Control *api;
|
||||
|
||||
the_information = _Objects_Get_information_id( the_thread->Object.id );
|
||||
|
||||
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
|
||||
|
||||
|
||||
/*
|
||||
* The_information has to be non-NULL. Otherwise, we couldn't be
|
||||
* running in a thread of this API and class.
|
||||
@@ -51,6 +57,31 @@ void _POSIX_Thread_Exit(
|
||||
|
||||
the_thread->Wait.return_argument = value_ptr;
|
||||
|
||||
/*
|
||||
* Process join
|
||||
*/
|
||||
if ( api->detachstate == PTHREAD_CREATE_JOINABLE ) {
|
||||
unblocked = _Thread_queue_Dequeue( &api->Join_List );
|
||||
if ( unblocked ) {
|
||||
do {
|
||||
*(void **)unblocked->Wait.return_argument = value_ptr;
|
||||
} while ( (unblocked = _Thread_queue_Dequeue( &api->Join_List )) );
|
||||
} else {
|
||||
_Thread_Set_state(
|
||||
the_thread,
|
||||
STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT
|
||||
);
|
||||
_RTEMS_Unlock_allocator();
|
||||
_Thread_Enable_dispatch();
|
||||
/* now waiting for thread to arrive */
|
||||
_RTEMS_Lock_allocator();
|
||||
_Thread_Disable_dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now shut down the thread
|
||||
*/
|
||||
_Thread_Close( the_information, the_thread );
|
||||
|
||||
_POSIX_Threads_Free( the_thread );
|
||||
|
||||
@@ -52,12 +52,18 @@ int pthread_join(
|
||||
* Put ourself on the threads join list
|
||||
*/
|
||||
|
||||
_Thread_Executing->Wait.return_argument = &return_pointer;
|
||||
|
||||
_Thread_queue_Enter_critical_section( &api->Join_List );
|
||||
|
||||
_Thread_queue_Enqueue( &api->Join_List, WATCHDOG_NO_TIMEOUT );
|
||||
|
||||
if ( the_thread->current_state ==
|
||||
(STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT) ) {
|
||||
return_pointer = the_thread->Wait.return_argument;
|
||||
_Thread_Clear_state(
|
||||
the_thread,
|
||||
(STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT)
|
||||
);
|
||||
} else {
|
||||
_Thread_Executing->Wait.return_argument = &return_pointer;
|
||||
_Thread_queue_Enter_critical_section( &api->Join_List );
|
||||
_Thread_queue_Enqueue( &api->Join_List, WATCHDOG_NO_TIMEOUT );
|
||||
}
|
||||
_Thread_Enable_dispatch();
|
||||
|
||||
if ( value_ptr )
|
||||
|
||||
Reference in New Issue
Block a user