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:55 +00:00
parent 1fc9ef5433
commit ffb8c77e23
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-24 Joel Sherrill <joel.sherrilL@OARcorp.com> 2011-07-24 Joel Sherrill <joel.sherrilL@OARcorp.com>
PR 1839/filesystem PR 1839/filesystem

View File

@@ -3,7 +3,7 @@
* *
* NOTE: Key destructors are executed in the POSIX api delete extension. * 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). * On-Line Applications Research Corporation (OAR).
* *
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
@@ -26,15 +26,21 @@
#include <rtems/score/thread.h> #include <rtems/score/thread.h>
#include <rtems/posix/pthread.h> #include <rtems/posix/pthread.h>
void _POSIX_Thread_Exit( void _POSIX_Thread_Exit(
Thread_Control *the_thread, Thread_Control *the_thread,
void *value_ptr 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 ); 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 * The_information has to be non-NULL. Otherwise, we couldn't be
* running in a thread of this API and class. * running in a thread of this API and class.
@@ -52,6 +58,31 @@ void _POSIX_Thread_Exit(
the_thread->Wait.return_argument = value_ptr; 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 ); _Thread_Close( the_information, the_thread );
_POSIX_Threads_Free( the_thread ); _POSIX_Threads_Free( the_thread );

View File

@@ -52,12 +52,18 @@ int pthread_join(
* Put ourself on the threads join list * Put ourself on the threads join list
*/ */
_Thread_Executing->Wait.return_argument = &return_pointer; if ( the_thread->current_state ==
(STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT) ) {
_Thread_queue_Enter_critical_section( &api->Join_List ); return_pointer = the_thread->Wait.return_argument;
_Thread_Clear_state(
_Thread_queue_Enqueue( &api->Join_List, WATCHDOG_NO_TIMEOUT ); 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(); _Thread_Enable_dispatch();
if ( value_ptr ) if ( value_ptr )