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:
Joel Sherrill
2011-07-31 16:16:30 +00:00
parent a9ed9230c6
commit 1389334318
3 changed files with 53 additions and 8 deletions

View File

@@ -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

View File

@@ -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 );

View File

@@ -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 )