forked from Imagelibrary/rtems
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-24 Joel Sherrill <joel.sherrilL@OARcorp.com>
|
2011-07-24 Joel Sherrill <joel.sherrilL@OARcorp.com>
|
||||||
|
|
||||||
PR 1839/filesystem
|
PR 1839/filesystem
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
Reference in New Issue
Block a user