2002-09-11 Robert Collins <rbtcollins@hotmail.com>
* init.cc (dll_entry): On thread detach, if the thread hasn't exit()ed, do so. * pthread.cc (pthread_getsequence_np): Remove the __pthread_getsequence_np wrapper. This requires errno.h. * thread.cc (pthread::self): Instantiate a new pthread object when called and none exists. return a NULL object if instantiation fails. (pthread::precreate): Factor out common code. (pthread::postcreate): Ditto. (pthread::create): Ditto. (pthread::exit): Remove the TLS value when we exit to prevent double exits. (MTinterface::Init): Bugfix - don't mark the TLS index as created if one was not allocated. Apply Extract Method to move pthread specific initialisation into pthread. (pthread::initMainThread): Extracted method from MTinterface::Init. (pthread::setTlsSelfPointer): Extracted method from various pthread calls, to make reading those functions easier. (pthread::setThreadIdtoCurrent): Ditto. (pthread::cancel_self): Bring into the .cc file, it's only used within the class. (pthread::getThreadId): Ditto. (pthread::thread_init_wrapper): Apply Extract Method to the TLS setting logic. (pthread::isGoodObject): Extracted method from various pthread wrapper calls, for clarity of reading. (pthread::getsequence_np): Converted from __pthread_getsquence_np. (__pthread_create): Apply Extract Method to the object validation. (__pthread_cancel): Ditto. (__pthread_join): Ditto. (__pthread_detach): Ditto. (__pthread_suspend): Ditto. (__pthread_continue): Ditto. (__pthread_getschedparam): Ditto. (__pthread_getsequence_np): Remove. (__pthread_setschedparam): Apply Extract Method to the object validation. (pthreadNull::getNullpthread): New method, return the pthreadNull object. (pthreadNull::pthreadNull): Private constructor to prevent accidental use. (pthreadNull::~pthreadNull): Prevent compile warnings. (pthreadNull::create): Override pthread behaviour. (pthreadNull::exit): Ditto. (pthreadNull::cancel): Ditto. (pthreadNull::testcancel): Ditto. (pthreadNull::setcancelstate): Ditto. (pthreadNull::setcanceltype): Ditto. (pthreadNull::push_cleanup_handler): Ditto. (pthreadNull::pop_cleanup_handler): Ditto. (pthreadNull::getsequence_np): Ditto. (pthreadNull::_instance): Ditto. * thread.h (pthread): Declare pre- and post-create. Move GetThreadId to private scope and rename to getThreadId. Move setThreadIdtoCurrent to private scope. Make create virtual. Make ~pthread virtual. Declare initMainThread. Declare isGoodObject. Make exit virtual. Make cancel virtual. Make testcancel virtual. Make setcancelstate virtual. Make setcanceltype virtual. Make push_cleanup_handler virtual. Make pop_cleanup_handler virtual. Declare getsequence_np. Declare setTlsSelfPointer. (pthreadNull): New null object class for pthread. (__pthread_getsequence_np): Remove.
This commit is contained in:
parent
0812076923
commit
4e78617321
|
@ -1,3 +1,77 @@
|
||||||
|
2002-09-11 Robert Collins <rbtcollins@hotmail.com>
|
||||||
|
|
||||||
|
* init.cc (dll_entry): On thread detach, if the thread hasn't
|
||||||
|
exit()ed, do so.
|
||||||
|
* pthread.cc (pthread_getsequence_np): Remove the
|
||||||
|
__pthread_getsequence_np wrapper. This requires errno.h.
|
||||||
|
* thread.cc (pthread::self): Instantiate a new pthread object
|
||||||
|
when called and none exists. return a NULL object if instantiation
|
||||||
|
fails.
|
||||||
|
(pthread::precreate): Factor out common code.
|
||||||
|
(pthread::postcreate): Ditto.
|
||||||
|
(pthread::create): Ditto.
|
||||||
|
(pthread::exit): Remove the TLS value when we exit to prevent
|
||||||
|
double exits.
|
||||||
|
(MTinterface::Init): Bugfix - don't mark the TLS index as created
|
||||||
|
if one was not allocated.
|
||||||
|
Apply Extract Method to move pthread specific initialisation into
|
||||||
|
pthread.
|
||||||
|
(pthread::initMainThread): Extracted method from MTinterface::Init.
|
||||||
|
(pthread::setTlsSelfPointer): Extracted method from various pthread
|
||||||
|
calls, to make reading those functions easier.
|
||||||
|
(pthread::setThreadIdtoCurrent): Ditto.
|
||||||
|
(pthread::cancel_self): Bring into the .cc file, it's only used
|
||||||
|
within the class.
|
||||||
|
(pthread::getThreadId): Ditto.
|
||||||
|
(pthread::thread_init_wrapper): Apply Extract Method to the TLS
|
||||||
|
setting logic.
|
||||||
|
(pthread::isGoodObject): Extracted method from various pthread
|
||||||
|
wrapper calls, for clarity of reading.
|
||||||
|
(pthread::getsequence_np): Converted from __pthread_getsquence_np.
|
||||||
|
(__pthread_create): Apply Extract Method to the object validation.
|
||||||
|
(__pthread_cancel): Ditto.
|
||||||
|
(__pthread_join): Ditto.
|
||||||
|
(__pthread_detach): Ditto.
|
||||||
|
(__pthread_suspend): Ditto.
|
||||||
|
(__pthread_continue): Ditto.
|
||||||
|
(__pthread_getschedparam): Ditto.
|
||||||
|
(__pthread_getsequence_np): Remove.
|
||||||
|
(__pthread_setschedparam): Apply Extract Method to the object
|
||||||
|
validation.
|
||||||
|
(pthreadNull::getNullpthread): New method, return the pthreadNull
|
||||||
|
object.
|
||||||
|
(pthreadNull::pthreadNull): Private constructor to prevent accidental
|
||||||
|
use.
|
||||||
|
(pthreadNull::~pthreadNull): Prevent compile warnings.
|
||||||
|
(pthreadNull::create): Override pthread behaviour.
|
||||||
|
(pthreadNull::exit): Ditto.
|
||||||
|
(pthreadNull::cancel): Ditto.
|
||||||
|
(pthreadNull::testcancel): Ditto.
|
||||||
|
(pthreadNull::setcancelstate): Ditto.
|
||||||
|
(pthreadNull::setcanceltype): Ditto.
|
||||||
|
(pthreadNull::push_cleanup_handler): Ditto.
|
||||||
|
(pthreadNull::pop_cleanup_handler): Ditto.
|
||||||
|
(pthreadNull::getsequence_np): Ditto.
|
||||||
|
(pthreadNull::_instance): Ditto.
|
||||||
|
* thread.h (pthread): Declare pre- and post-create.
|
||||||
|
Move GetThreadId to private scope and rename to getThreadId.
|
||||||
|
Move setThreadIdtoCurrent to private scope.
|
||||||
|
Make create virtual.
|
||||||
|
Make ~pthread virtual.
|
||||||
|
Declare initMainThread.
|
||||||
|
Declare isGoodObject.
|
||||||
|
Make exit virtual.
|
||||||
|
Make cancel virtual.
|
||||||
|
Make testcancel virtual.
|
||||||
|
Make setcancelstate virtual.
|
||||||
|
Make setcanceltype virtual.
|
||||||
|
Make push_cleanup_handler virtual.
|
||||||
|
Make pop_cleanup_handler virtual.
|
||||||
|
Declare getsequence_np.
|
||||||
|
Declare setTlsSelfPointer.
|
||||||
|
(pthreadNull): New null object class for pthread.
|
||||||
|
(__pthread_getsequence_np): Remove.
|
||||||
|
|
||||||
2002-09-13 Corinna Vinschen <corinna@vinschen.de>
|
2002-09-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* syscalls.cc (seteuid32): Treat ILLEGAL_UID invalid.
|
* syscalls.cc (seteuid32): Treat ILLEGAL_UID invalid.
|
||||||
|
|
|
@ -35,6 +35,13 @@ WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load)
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
|
pthread *thisthread = (pthread *) TlsGetValue (
|
||||||
|
user_data->threadinterface->thread_self_dwTlsIndex);
|
||||||
|
if (thisthread) {
|
||||||
|
/* Some non-pthread call created this thread,
|
||||||
|
* but we need to clean it up */
|
||||||
|
thisthread->exit(0);
|
||||||
|
}
|
||||||
#if 0 // FIXME: REINSTATE SOON
|
#if 0 // FIXME: REINSTATE SOON
|
||||||
waitq *w;
|
waitq *w;
|
||||||
if ((w = waitq_storage.get ()) != NULL)
|
if ((w = waitq_storage.get ()) != NULL)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "errno.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
@ -173,7 +174,9 @@ pthread_continue (pthread_t thread)
|
||||||
unsigned long
|
unsigned long
|
||||||
pthread_getsequence_np (pthread_t * thread)
|
pthread_getsequence_np (pthread_t * thread)
|
||||||
{
|
{
|
||||||
return __pthread_getsequence_np (thread);
|
if (!pthread::isGoodObject (thread))
|
||||||
|
return EINVAL;
|
||||||
|
return (*thread)->getsequence_np();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Thread SpecificData */
|
/* Thread SpecificData */
|
||||||
|
|
|
@ -283,20 +283,18 @@ MTinterface::Init (int forked)
|
||||||
|
|
||||||
if (!indexallocated)
|
if (!indexallocated)
|
||||||
{
|
{
|
||||||
indexallocated = (-1);
|
|
||||||
thread_self_dwTlsIndex = TlsAlloc ();
|
thread_self_dwTlsIndex = TlsAlloc ();
|
||||||
if (thread_self_dwTlsIndex == TLS_OUT_OF_INDEXES)
|
if (thread_self_dwTlsIndex == TLS_OUT_OF_INDEXES)
|
||||||
system_printf
|
system_printf
|
||||||
("local storage for thread couldn't be set\nThis means that we are not thread safe!");
|
("local storage for thread couldn't be set\nThis means that we are not thread safe!");
|
||||||
|
else
|
||||||
|
indexallocated = (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
concurrency = 0;
|
concurrency = 0;
|
||||||
threadcount = 1; /*1 current thread when Init occurs.*/
|
threadcount = 1; /*1 current thread when Init occurs.*/
|
||||||
|
|
||||||
mainthread.win32_obj_id = myself->hProcess;
|
pthread::initMainThread(&mainthread, myself->hProcess);
|
||||||
mainthread.setThreadIdtoCurrent ();
|
|
||||||
/*store the main thread's self pointer */
|
|
||||||
TlsSetValue (thread_self_dwTlsIndex, &mainthread);
|
|
||||||
|
|
||||||
if (forked)
|
if (forked)
|
||||||
return;
|
return;
|
||||||
|
@ -346,11 +344,35 @@ MTinterface::fixup_after_fork (void)
|
||||||
/* pthread calls */
|
/* pthread calls */
|
||||||
|
|
||||||
/* static methods */
|
/* static methods */
|
||||||
|
void
|
||||||
|
pthread::initMainThread(pthread *mainThread, HANDLE win32_obj_id)
|
||||||
|
{
|
||||||
|
mainThread->win32_obj_id = win32_obj_id;
|
||||||
|
mainThread->setThreadIdtoCurrent ();
|
||||||
|
setTlsSelfPointer(mainThread);
|
||||||
|
}
|
||||||
|
|
||||||
pthread *
|
pthread *
|
||||||
pthread::self ()
|
pthread::self ()
|
||||||
{
|
{
|
||||||
return (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
|
pthread *temp = (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
|
||||||
|
if (temp)
|
||||||
|
return temp;
|
||||||
|
temp = new pthread ();
|
||||||
|
temp->precreate (NULL);
|
||||||
|
if (!temp->magic) {
|
||||||
|
delete temp;
|
||||||
|
return pthreadNull::getNullpthread();
|
||||||
|
}
|
||||||
|
temp->postcreate ();
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::setTlsSelfPointer(pthread *thisThread)
|
||||||
|
{
|
||||||
|
/*the OS doesn't check this for <= 64 Tls entries (pre win2k) */
|
||||||
|
TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thisThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* member methods */
|
/* member methods */
|
||||||
|
@ -368,10 +390,14 @@ pthread::~pthread ()
|
||||||
CloseHandle (cancel_event);
|
CloseHandle (cancel_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::setThreadIdtoCurrent ()
|
||||||
|
{
|
||||||
|
thread_id = GetCurrentThreadId ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
pthread::precreate (pthread_attr *newattr)
|
||||||
void *threadarg)
|
|
||||||
{
|
{
|
||||||
pthread_mutex *verifyable_mutex_obj = &mutex;
|
pthread_mutex *verifyable_mutex_obj = &mutex;
|
||||||
|
|
||||||
|
@ -386,8 +412,6 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
||||||
attr.inheritsched = newattr->inheritsched;
|
attr.inheritsched = newattr->inheritsched;
|
||||||
attr.stacksize = newattr->stacksize;
|
attr.stacksize = newattr->stacksize;
|
||||||
}
|
}
|
||||||
function = func;
|
|
||||||
arg = threadarg;
|
|
||||||
|
|
||||||
if (verifyable_object_isvalid (&verifyable_mutex_obj, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
|
if (verifyable_object_isvalid (&verifyable_mutex_obj, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
|
||||||
{
|
{
|
||||||
|
@ -405,6 +429,17 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
||||||
magic = 0;
|
magic = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
||||||
|
void *threadarg)
|
||||||
|
{
|
||||||
|
precreate (newattr);
|
||||||
|
if (!magic)
|
||||||
|
return;
|
||||||
|
function = func;
|
||||||
|
arg = threadarg;
|
||||||
|
|
||||||
win32_obj_id = ::CreateThread (&sec_none_nih, attr.stacksize,
|
win32_obj_id = ::CreateThread (&sec_none_nih, attr.stacksize,
|
||||||
(LPTHREAD_START_ROUTINE) thread_init_wrapper,
|
(LPTHREAD_START_ROUTINE) thread_init_wrapper,
|
||||||
|
@ -415,17 +450,22 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
||||||
thread_printf ("CreateThread failed: this %p LastError %E", this);
|
thread_printf ("CreateThread failed: this %p LastError %E", this);
|
||||||
magic = 0;
|
magic = 0;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
postcreate ();
|
||||||
InterlockedIncrement (&MT_INTERFACE->threadcount);
|
|
||||||
/*FIXME: set the priority appropriately for system contention scope */
|
|
||||||
if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
|
|
||||||
{
|
|
||||||
/*FIXME: set the scheduling settings for the new thread */
|
|
||||||
/*sched_thread_setparam (win32_obj_id, attr.schedparam); */
|
|
||||||
}
|
|
||||||
ResumeThread (win32_obj_id);
|
ResumeThread (win32_obj_id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::postcreate ()
|
||||||
|
{
|
||||||
|
InterlockedIncrement (&MT_INTERFACE->threadcount);
|
||||||
|
/*FIXME: set the priority appropriately for system contention scope */
|
||||||
|
if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
|
||||||
|
{
|
||||||
|
/*FIXME: set the scheduling settings for the new thread */
|
||||||
|
/*sched_thread_setparam (win32_obj_id, attr.schedparam); */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -448,6 +488,9 @@ pthread::exit (void *value_ptr)
|
||||||
mutex.UnLock ();
|
mutex.UnLock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Prevent DLL_THREAD_DETACH Attempting to clean us up */
|
||||||
|
setTlsSelfPointer(0);
|
||||||
|
|
||||||
if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
|
if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
|
||||||
::exit (0);
|
::exit (0);
|
||||||
else
|
else
|
||||||
|
@ -764,6 +807,18 @@ pthread::pop_all_cleanup_handlers ()
|
||||||
pop_cleanup_handler (1);
|
pop_cleanup_handler (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::cancel_self()
|
||||||
|
{
|
||||||
|
exit (PTHREAD_CANCELED);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
pthread::getThreadId()
|
||||||
|
{
|
||||||
|
return thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
|
pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
|
||||||
joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
|
joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
|
||||||
inheritsched (PTHREAD_INHERIT_SCHED), stacksize (0)
|
inheritsched (PTHREAD_INHERIT_SCHED), stacksize (0)
|
||||||
|
@ -1278,8 +1333,7 @@ pthread::thread_init_wrapper (void *_arg)
|
||||||
if (!TlsSetValue (MT_INTERFACE->reent_index, &local_reent))
|
if (!TlsSetValue (MT_INTERFACE->reent_index, &local_reent))
|
||||||
system_printf ("local storage for thread couldn't be set");
|
system_printf ("local storage for thread couldn't be set");
|
||||||
|
|
||||||
/*the OS doesn't check this for <= 64 Tls entries (pre win2k) */
|
setTlsSelfPointer(thread);
|
||||||
TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thread);
|
|
||||||
|
|
||||||
thread->mutex.Lock ();
|
thread->mutex.Lock ();
|
||||||
// if thread is detached force cleanup on exit
|
// if thread is detached force cleanup on exit
|
||||||
|
@ -1308,6 +1362,20 @@ pthread::thread_init_wrapper (void *_arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
pthread::isGoodObject (pthread_t *thread)
|
||||||
|
{
|
||||||
|
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
pthread::getsequence_np ()
|
||||||
|
{
|
||||||
|
return getThreadId ();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
__pthread_create (pthread_t *thread, const pthread_attr_t *attr,
|
__pthread_create (pthread_t *thread, const pthread_attr_t *attr,
|
||||||
void *(*start_routine) (void *), void *arg)
|
void *(*start_routine) (void *), void *arg)
|
||||||
|
@ -1318,7 +1386,7 @@ __pthread_create (pthread_t *thread, const pthread_attr_t *attr,
|
||||||
|
|
||||||
*thread = new pthread ();
|
*thread = new pthread ();
|
||||||
(*thread)->create (start_routine, attr ? *attr : NULL, arg);
|
(*thread)->create (start_routine, attr ? *attr : NULL, arg);
|
||||||
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (thread))
|
||||||
{
|
{
|
||||||
delete (*thread);
|
delete (*thread);
|
||||||
*thread = NULL;
|
*thread = NULL;
|
||||||
|
@ -1355,7 +1423,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
|
||||||
int
|
int
|
||||||
__pthread_cancel (pthread_t thread)
|
__pthread_cancel (pthread_t thread)
|
||||||
{
|
{
|
||||||
if (verifyable_object_isvalid (&thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (&thread))
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
return thread->cancel ();
|
return thread->cancel ();
|
||||||
|
@ -1642,7 +1710,7 @@ __pthread_join (pthread_t *thread, void **return_val)
|
||||||
*return_val = NULL;
|
*return_val = NULL;
|
||||||
|
|
||||||
/*FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
|
/*FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
|
||||||
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (thread))
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
if (__pthread_equal(thread,&joiner))
|
if (__pthread_equal(thread,&joiner))
|
||||||
|
@ -1675,7 +1743,7 @@ __pthread_join (pthread_t *thread, void **return_val)
|
||||||
int
|
int
|
||||||
__pthread_detach (pthread_t *thread)
|
__pthread_detach (pthread_t *thread)
|
||||||
{
|
{
|
||||||
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (thread))
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
(*thread)->mutex.Lock ();
|
(*thread)->mutex.Lock ();
|
||||||
|
@ -1706,7 +1774,7 @@ __pthread_detach (pthread_t *thread)
|
||||||
int
|
int
|
||||||
__pthread_suspend (pthread_t *thread)
|
__pthread_suspend (pthread_t *thread)
|
||||||
{
|
{
|
||||||
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (thread))
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
if ((*thread)->suspended == false)
|
if ((*thread)->suspended == false)
|
||||||
|
@ -1722,7 +1790,7 @@ __pthread_suspend (pthread_t *thread)
|
||||||
int
|
int
|
||||||
__pthread_continue (pthread_t *thread)
|
__pthread_continue (pthread_t *thread)
|
||||||
{
|
{
|
||||||
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (thread))
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
|
|
||||||
if ((*thread)->suspended == true)
|
if ((*thread)->suspended == true)
|
||||||
|
@ -1746,7 +1814,7 @@ int
|
||||||
__pthread_getschedparam (pthread_t thread, int *policy,
|
__pthread_getschedparam (pthread_t thread, int *policy,
|
||||||
struct sched_param *param)
|
struct sched_param *param)
|
||||||
{
|
{
|
||||||
if (verifyable_object_isvalid (&thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (&thread))
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
*policy = SCHED_FIFO;
|
*policy = SCHED_FIFO;
|
||||||
/*we don't return the current effective priority, we return the current requested
|
/*we don't return the current effective priority, we return the current requested
|
||||||
|
@ -1755,15 +1823,6 @@ __pthread_getschedparam (pthread_t thread, int *policy,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned long
|
|
||||||
__pthread_getsequence_np (pthread_t *thread)
|
|
||||||
{
|
|
||||||
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
|
||||||
return EINVAL;
|
|
||||||
return (*thread)->GetThreadId ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Thread SpecificData */
|
/*Thread SpecificData */
|
||||||
int
|
int
|
||||||
__pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
|
__pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
|
||||||
|
@ -1812,7 +1871,7 @@ int
|
||||||
__pthread_setschedparam (pthread_t thread, int policy,
|
__pthread_setschedparam (pthread_t thread, int policy,
|
||||||
const struct sched_param *param)
|
const struct sched_param *param)
|
||||||
{
|
{
|
||||||
if (verifyable_object_isvalid (&thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (&thread))
|
||||||
return ESRCH;
|
return ESRCH;
|
||||||
if (policy != SCHED_FIFO)
|
if (policy != SCHED_FIFO)
|
||||||
return ENOTSUP;
|
return ENOTSUP;
|
||||||
|
@ -2045,7 +2104,7 @@ __pthread_kill (pthread_t thread, int sig)
|
||||||
// lock myself, for the use of thread2signal
|
// lock myself, for the use of thread2signal
|
||||||
// two different kills might clash: FIXME
|
// two different kills might clash: FIXME
|
||||||
|
|
||||||
if (verifyable_object_isvalid (&thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (!pthread::isGoodObject (&thread))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
if (thread->sigs)
|
if (thread->sigs)
|
||||||
|
@ -2401,4 +2460,73 @@ __sem_post (sem_t *sem)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pthreadNull */
|
||||||
|
pthread *
|
||||||
|
pthreadNull::getNullpthread()
|
||||||
|
{
|
||||||
|
/* because of weird entry points */
|
||||||
|
_instance.magic = 0;
|
||||||
|
return &_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthreadNull::pthreadNull()
|
||||||
|
{
|
||||||
|
/* Mark ourselves as invalid */
|
||||||
|
magic = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthreadNull::~pthreadNull()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthreadNull::create (void *(*)(void *), pthread_attr *, void *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthreadNull::exit (void *value_ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pthreadNull::cancel ()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthreadNull::testcancel ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pthreadNull::setcancelstate (int state, int *oldstate)
|
||||||
|
{
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pthreadNull::setcanceltype (int type, int *oldtype)
|
||||||
|
{
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthreadNull::push_cleanup_handler (__pthread_cleanup_handler *handler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthreadNull::pop_cleanup_handler (int const execute)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
unsigned long
|
||||||
|
pthreadNull::getsequence_np()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthreadNull pthreadNull::_instance = pthreadNull ();
|
||||||
|
|
||||||
#endif // MT_SAFE
|
#endif // MT_SAFE
|
||||||
|
|
|
@ -270,43 +270,35 @@ public:
|
||||||
pthread_t joiner;
|
pthread_t joiner;
|
||||||
// int joinable;
|
// int joinable;
|
||||||
|
|
||||||
DWORD GetThreadId ()
|
|
||||||
{
|
|
||||||
return thread_id;
|
|
||||||
}
|
|
||||||
void setThreadIdtoCurrent ()
|
|
||||||
{
|
|
||||||
thread_id = GetCurrentThreadId ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* signal handling */
|
/* signal handling */
|
||||||
struct sigaction *sigs;
|
struct sigaction *sigs;
|
||||||
sigset_t *sigmask;
|
sigset_t *sigmask;
|
||||||
LONG *sigtodo;
|
LONG *sigtodo;
|
||||||
void create (void *(*)(void *), pthread_attr *, void *);
|
virtual void create (void *(*)(void *), pthread_attr *, void *);
|
||||||
|
|
||||||
pthread ();
|
pthread ();
|
||||||
~pthread ();
|
virtual ~pthread ();
|
||||||
|
|
||||||
void exit (void *value_ptr);
|
static void initMainThread(pthread *, HANDLE);
|
||||||
|
static bool isGoodObject(pthread_t *);
|
||||||
|
|
||||||
int cancel ();
|
virtual void exit (void *value_ptr);
|
||||||
void testcancel ();
|
|
||||||
void cancel_self ()
|
virtual int cancel ();
|
||||||
{
|
virtual void testcancel ();
|
||||||
exit (PTHREAD_CANCELED);
|
|
||||||
}
|
|
||||||
static void static_cancel_self ();
|
static void static_cancel_self ();
|
||||||
|
|
||||||
int setcancelstate (int state, int *oldstate);
|
virtual int setcancelstate (int state, int *oldstate);
|
||||||
int setcanceltype (int type, int *oldtype);
|
virtual int setcanceltype (int type, int *oldtype);
|
||||||
|
|
||||||
void push_cleanup_handler (__pthread_cleanup_handler *handler);
|
virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
|
||||||
void pop_cleanup_handler (int const execute);
|
virtual void pop_cleanup_handler (int const execute);
|
||||||
|
|
||||||
static pthread* self ();
|
static pthread* self ();
|
||||||
static void *thread_init_wrapper (void *);
|
static void *thread_init_wrapper (void *);
|
||||||
|
|
||||||
|
virtual unsigned long getsequence_np();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DWORD thread_id;
|
DWORD thread_id;
|
||||||
__pthread_cleanup_handler *cleanup_stack;
|
__pthread_cleanup_handler *cleanup_stack;
|
||||||
|
@ -316,6 +308,36 @@ private:
|
||||||
friend int __pthread_detach (pthread_t * thread);
|
friend int __pthread_detach (pthread_t * thread);
|
||||||
|
|
||||||
void pop_all_cleanup_handlers (void);
|
void pop_all_cleanup_handlers (void);
|
||||||
|
void precreate (pthread_attr *);
|
||||||
|
void postcreate ();
|
||||||
|
void setThreadIdtoCurrent();
|
||||||
|
static void setTlsSelfPointer(pthread *);
|
||||||
|
void cancel_self ();
|
||||||
|
DWORD getThreadId ();
|
||||||
|
};
|
||||||
|
|
||||||
|
class pthreadNull : public pthread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static pthread *getNullpthread();
|
||||||
|
~pthreadNull();
|
||||||
|
|
||||||
|
/* From pthread These should never get called
|
||||||
|
* as the ojbect is not verifyable
|
||||||
|
*/
|
||||||
|
void create (void *(*)(void *), pthread_attr *, void *);
|
||||||
|
void exit (void *value_ptr);
|
||||||
|
int cancel ();
|
||||||
|
void testcancel ();
|
||||||
|
int setcancelstate (int state, int *oldstate);
|
||||||
|
int setcanceltype (int type, int *oldtype);
|
||||||
|
void push_cleanup_handler (__pthread_cleanup_handler *handler);
|
||||||
|
void pop_cleanup_handler (int const execute);
|
||||||
|
unsigned long getsequence_np();
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthreadNull ();
|
||||||
|
static pthreadNull _instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
class pthread_condattr:public verifyable_object
|
class pthread_condattr:public verifyable_object
|
||||||
|
@ -458,8 +480,6 @@ int __pthread_attr_setstackaddr (pthread_attr_t *, void *);
|
||||||
int __pthread_suspend (pthread_t * thread);
|
int __pthread_suspend (pthread_t * thread);
|
||||||
int __pthread_continue (pthread_t * thread);
|
int __pthread_continue (pthread_t * thread);
|
||||||
|
|
||||||
unsigned long __pthread_getsequence_np (pthread_t * thread);
|
|
||||||
|
|
||||||
/* Thread SpecificData */
|
/* Thread SpecificData */
|
||||||
int __pthread_key_create (pthread_key_t * key, void (*destructor) (void *));
|
int __pthread_key_create (pthread_key_t * key, void (*destructor) (void *));
|
||||||
int __pthread_key_delete (pthread_key_t key);
|
int __pthread_key_delete (pthread_key_t key);
|
||||||
|
|
Loading…
Reference in New Issue