2002-11-05 Thomas Pfaff <tpfaff@gmx.net>
* dcrt0.cc (dll_crt0_1): Add call to pthread::initMainThread to initialize mainthread when it is safe to call new. * init.cc (dll_entry): Change call to store reents in tls key. * thread.cc (_reent_clib) : Change call to get reents from tls key. (_reent_winsup): Ditto. (MTinterface::Init): Key handling changed. Remove initialization of member variables. (MTinterface::fixup_after_fork): Reinitialize mainthread object after fork. Reset threadount to 1. (pthread::initMainThread): Create mainthread object dynamically. and initialize with valid handles. (pthread::self): Remove calls to create thread objects. (pthread::setTlsSelfPointer): Change call to store thread self handle in tls key. (pthread::getTlsSelfPointer): New static method. (pthread::exit): Remove setTlsSelfPointer call. (pthread::initCurrentThread): New method. (pthread::thread_init_wrapper): Change call to store thread self handle in tls key. (pthread::join): Check for a valid joiner. (pthreadNull::pthreadNull): Mark Null object as detached. (pthreadNull::exit): Terminate thread via ExitThread. * thread.h (pthread::initMainThread): Change parameter in function call. (pthread::getTlsSelfPointer): New static method. (pthread::initCurrentThread): New method. (MTinterface::reent_key): Remove. (MTinterface::thread_self_dwTlsIndex): Ditto.. (MTinterface::indexallocated): Ditto. (MTinterface::mainthread): Ditto. (MTinterface::reent_key): New member. (MTinterface::thread_self_key): Ditto. (MTinterface::MTinterface): Initialize all members.
This commit is contained in:
parent
4f0de34d37
commit
f8c8e13b7e
@ -1,3 +1,40 @@
|
|||||||
|
2002-11-05 Thomas Pfaff <tpfaff@gmx.net>
|
||||||
|
|
||||||
|
* dcrt0.cc (dll_crt0_1): Add call to pthread::initMainThread to
|
||||||
|
initialize mainthread when it is safe to call new.
|
||||||
|
* init.cc (dll_entry): Change call to store reents in tls key.
|
||||||
|
* thread.cc (_reent_clib) : Change call to get reents from tls
|
||||||
|
key.
|
||||||
|
(_reent_winsup): Ditto.
|
||||||
|
(MTinterface::Init): Key handling changed. Remove initialization
|
||||||
|
of member variables.
|
||||||
|
(MTinterface::fixup_after_fork): Reinitialize mainthread object
|
||||||
|
after fork. Reset threadount to 1.
|
||||||
|
(pthread::initMainThread): Create mainthread object dynamically.
|
||||||
|
and initialize with valid handles.
|
||||||
|
(pthread::self): Remove calls to create thread objects.
|
||||||
|
(pthread::setTlsSelfPointer): Change call to store thread self
|
||||||
|
handle in tls key.
|
||||||
|
(pthread::getTlsSelfPointer): New static method.
|
||||||
|
(pthread::exit): Remove setTlsSelfPointer call.
|
||||||
|
(pthread::initCurrentThread): New method.
|
||||||
|
(pthread::thread_init_wrapper): Change call to store thread self
|
||||||
|
handle in tls key.
|
||||||
|
(pthread::join): Check for a valid joiner.
|
||||||
|
(pthreadNull::pthreadNull): Mark Null object as detached.
|
||||||
|
(pthreadNull::exit): Terminate thread via ExitThread.
|
||||||
|
* thread.h (pthread::initMainThread): Change parameter in function
|
||||||
|
call.
|
||||||
|
(pthread::getTlsSelfPointer): New static method.
|
||||||
|
(pthread::initCurrentThread): New method.
|
||||||
|
(MTinterface::reent_key): Remove.
|
||||||
|
(MTinterface::thread_self_dwTlsIndex): Ditto..
|
||||||
|
(MTinterface::indexallocated): Ditto.
|
||||||
|
(MTinterface::mainthread): Ditto.
|
||||||
|
(MTinterface::reent_key): New member.
|
||||||
|
(MTinterface::thread_self_key): Ditto.
|
||||||
|
(MTinterface::MTinterface): Initialize all members.
|
||||||
|
|
||||||
2002-11-23 Christopher Faylor <cgf@redhat.com>
|
2002-11-23 Christopher Faylor <cgf@redhat.com>
|
||||||
|
|
||||||
* wait.cc (wait4): Force pending signal delivery before waiting for
|
* wait.cc (wait4): Force pending signal delivery before waiting for
|
||||||
|
@ -628,6 +628,8 @@ dll_crt0_1 ()
|
|||||||
ProtectHandle (hMainThread);
|
ProtectHandle (hMainThread);
|
||||||
cygthread::init ();
|
cygthread::init ();
|
||||||
|
|
||||||
|
pthread::initMainThread (!user_data->forkee);
|
||||||
|
|
||||||
/* Initialize debug muto, if DLL is built with --enable-debugging.
|
/* Initialize debug muto, if DLL is built with --enable-debugging.
|
||||||
Need to do this before any helper threads start. */
|
Need to do this before any helper threads start. */
|
||||||
debug_init ();
|
debug_init ();
|
||||||
|
@ -27,12 +27,8 @@ WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load)
|
|||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
if (user_data->threadinterface)
|
if (MT_INTERFACE->reent_key.set (&MT_INTERFACE->reents))
|
||||||
{
|
|
||||||
if (!TlsSetValue (user_data->threadinterface->reent_index,
|
|
||||||
&user_data->threadinterface->reents))
|
|
||||||
api_fatal ("thread initialization failed");
|
api_fatal ("thread initialization failed");
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
/* not invoked */;
|
/* not invoked */;
|
||||||
|
@ -46,35 +46,29 @@ details. */
|
|||||||
|
|
||||||
extern int threadsafe;
|
extern int threadsafe;
|
||||||
|
|
||||||
#define MT_INTERFACE user_data->threadinterface
|
|
||||||
|
|
||||||
struct _reent *
|
struct _reent *
|
||||||
_reent_clib ()
|
_reent_clib ()
|
||||||
{
|
{
|
||||||
int tmp = GetLastError ();
|
|
||||||
struct __reent_t *_r =
|
struct __reent_t *_r =
|
||||||
(struct __reent_t *) TlsGetValue (MT_INTERFACE->reent_index);
|
(struct __reent_t *) MT_INTERFACE->reent_key.get ();
|
||||||
|
|
||||||
#ifdef _CYG_THREAD_FAILSAFE
|
#ifdef _CYG_THREAD_FAILSAFE
|
||||||
if (_r == 0)
|
if (_r == 0)
|
||||||
system_printf ("local thread storage not inited");
|
system_printf ("local thread storage not inited");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SetLastError (tmp);
|
|
||||||
return _r->_clib;
|
return _r->_clib;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _winsup_t *
|
struct _winsup_t *
|
||||||
_reent_winsup ()
|
_reent_winsup ()
|
||||||
{
|
{
|
||||||
int tmp = GetLastError ();
|
struct __reent_t *_r =
|
||||||
struct __reent_t *_r;
|
(struct __reent_t *) MT_INTERFACE->reent_key.get ();
|
||||||
_r = (struct __reent_t *) TlsGetValue (MT_INTERFACE->reent_index);
|
|
||||||
#ifdef _CYG_THREAD_FAILSAFE
|
#ifdef _CYG_THREAD_FAILSAFE
|
||||||
if (_r == 0)
|
if (_r == 0)
|
||||||
system_printf ("local thread storage not inited");
|
system_printf ("local thread storage not inited");
|
||||||
#endif
|
#endif
|
||||||
SetLastError (tmp);
|
|
||||||
return _r->_winsup;
|
return _r->_winsup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,39 +160,14 @@ ResourceLocks::Delete ()
|
|||||||
void
|
void
|
||||||
MTinterface::Init (int forked)
|
MTinterface::Init (int forked)
|
||||||
{
|
{
|
||||||
|
|
||||||
reent_index = TlsAlloc ();
|
|
||||||
reents._clib = _impure_ptr;
|
reents._clib = _impure_ptr;
|
||||||
reents._winsup = &winsup_reent;
|
reents._winsup = &winsup_reent;
|
||||||
|
|
||||||
winsup_reent._process_logmask = LOG_UPTO (LOG_DEBUG);
|
winsup_reent._process_logmask = LOG_UPTO (LOG_DEBUG);
|
||||||
|
|
||||||
TlsSetValue (reent_index, &reents);
|
if (!forked)
|
||||||
// the static reent_data will be used in the main thread
|
reent_key.set (&reents);
|
||||||
|
|
||||||
if (!indexallocated)
|
|
||||||
{
|
|
||||||
thread_self_dwTlsIndex = TlsAlloc ();
|
|
||||||
if (thread_self_dwTlsIndex == TLS_OUT_OF_INDEXES)
|
|
||||||
system_printf
|
|
||||||
("local storage for thread couldn't be set\nThis means that we are not thread safe!");
|
|
||||||
else
|
|
||||||
indexallocated = (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
concurrency = 0;
|
|
||||||
threadcount = 1; /* 1 current thread when Init occurs.*/
|
|
||||||
|
|
||||||
pthread::initMainThread (&mainthread, myself->hProcess);
|
|
||||||
pthread_mutex::initMutex ();
|
pthread_mutex::initMutex ();
|
||||||
|
|
||||||
if (forked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mutexs = NULL;
|
|
||||||
conds = NULL;
|
|
||||||
semaphores = NULL;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -233,40 +202,51 @@ MTinterface::fixup_after_fork (void)
|
|||||||
sem->fixup_after_fork ();
|
sem->fixup_after_fork ();
|
||||||
sem = sem->next;
|
sem = sem->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread::initMainThread (true);
|
||||||
|
|
||||||
|
threadcount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pthread calls */
|
/* pthread calls */
|
||||||
|
|
||||||
/* static methods */
|
/* static methods */
|
||||||
void
|
void
|
||||||
pthread::initMainThread (pthread *mainThread, HANDLE win32_obj_id)
|
pthread::initMainThread (bool do_init)
|
||||||
{
|
{
|
||||||
mainThread->win32_obj_id = win32_obj_id;
|
if (!do_init)
|
||||||
mainThread->setThreadIdtoCurrent ();
|
return;
|
||||||
setTlsSelfPointer (mainThread);
|
|
||||||
|
pthread *thread = getTlsSelfPointer ();
|
||||||
|
if (!thread)
|
||||||
|
{
|
||||||
|
thread = new pthread ();
|
||||||
|
if (!thread)
|
||||||
|
api_fatal ("failed to create mainthread object");
|
||||||
|
}
|
||||||
|
|
||||||
|
thread->initCurrentThread ();
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread *
|
pthread *
|
||||||
pthread::self ()
|
pthread::self ()
|
||||||
{
|
{
|
||||||
pthread *temp = (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
|
pthread *thread = getTlsSelfPointer ();
|
||||||
if (temp)
|
if (thread)
|
||||||
return temp;
|
return thread;
|
||||||
temp = new pthread ();
|
return pthreadNull::getNullpthread ();
|
||||||
temp->precreate (NULL);
|
|
||||||
if (!temp->magic) {
|
|
||||||
delete temp;
|
|
||||||
return pthreadNull::getNullpthread ();
|
|
||||||
}
|
|
||||||
temp->postcreate ();
|
|
||||||
return temp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pthread::setTlsSelfPointer (pthread *thisThread)
|
pthread::setTlsSelfPointer (pthread *thisThread)
|
||||||
{
|
{
|
||||||
/* the OS doesn't check this for <= 64 Tls entries (pre win2k) */
|
MT_INTERFACE->thread_self_key.set (thisThread);
|
||||||
TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thisThread);
|
}
|
||||||
|
|
||||||
|
pthread *
|
||||||
|
pthread::getTlsSelfPointer ()
|
||||||
|
{
|
||||||
|
return (pthread *) MT_INTERFACE->thread_self_key.get ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -384,9 +364,6 @@ 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
|
||||||
@ -715,6 +692,18 @@ pthread::getThreadId ()
|
|||||||
return thread_id;
|
return thread_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::initCurrentThread ()
|
||||||
|
{
|
||||||
|
cancel_event = ::CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||||
|
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
|
||||||
|
GetCurrentProcess (), &win32_obj_id,
|
||||||
|
0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||||
|
win32_obj_id = NULL;
|
||||||
|
setThreadIdtoCurrent ();
|
||||||
|
setTlsSelfPointer (this);
|
||||||
|
}
|
||||||
|
|
||||||
/* static members */
|
/* static members */
|
||||||
bool
|
bool
|
||||||
pthread_attr::isGoodObject (pthread_attr_t const *attr)
|
pthread_attr::isGoodObject (pthread_attr_t const *attr)
|
||||||
@ -1411,16 +1400,15 @@ pthread::thread_init_wrapper (void *_arg)
|
|||||||
|
|
||||||
local_winsup._process_logmask = LOG_UPTO (LOG_DEBUG);
|
local_winsup._process_logmask = LOG_UPTO (LOG_DEBUG);
|
||||||
|
|
||||||
/* This is not checked by the OS !! */
|
MT_INTERFACE->reent_key.set (&local_reent);
|
||||||
if (!TlsSetValue (MT_INTERFACE->reent_index, &local_reent))
|
|
||||||
system_printf ("local storage for thread couldn't be set");
|
|
||||||
|
|
||||||
|
thread->setThreadIdtoCurrent ();
|
||||||
setTlsSelfPointer (thread);
|
setTlsSelfPointer (thread);
|
||||||
|
|
||||||
thread->mutex.Lock ();
|
thread->mutex.Lock ();
|
||||||
// if thread is detached force cleanup on exit
|
// if thread is detached force cleanup on exit
|
||||||
if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
|
if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
|
||||||
thread->joiner = pthread::self ();
|
thread->joiner = thread;
|
||||||
thread->mutex.UnLock ();
|
thread->mutex.UnLock ();
|
||||||
|
|
||||||
#ifdef _CYG_THREAD_FAILSAFE
|
#ifdef _CYG_THREAD_FAILSAFE
|
||||||
@ -1787,6 +1775,9 @@ pthread::join (pthread_t *thread, void **return_val)
|
|||||||
{
|
{
|
||||||
pthread_t joiner = self ();
|
pthread_t joiner = self ();
|
||||||
|
|
||||||
|
if (!isGoodObject (&joiner))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
// Initialize return val with NULL
|
// Initialize return val with NULL
|
||||||
if (return_val)
|
if (return_val)
|
||||||
*return_val = NULL;
|
*return_val = NULL;
|
||||||
@ -2594,6 +2585,7 @@ pthreadNull::getNullpthread ()
|
|||||||
|
|
||||||
pthreadNull::pthreadNull ()
|
pthreadNull::pthreadNull ()
|
||||||
{
|
{
|
||||||
|
attr.joinable = PTHREAD_CREATE_DETACHED;
|
||||||
/* Mark ourselves as invalid */
|
/* Mark ourselves as invalid */
|
||||||
magic = 0;
|
magic = 0;
|
||||||
}
|
}
|
||||||
@ -2610,6 +2602,7 @@ pthreadNull::create (void *(*)(void *), pthread_attr *, void *)
|
|||||||
void
|
void
|
||||||
pthreadNull::exit (void *value_ptr)
|
pthreadNull::exit (void *value_ptr)
|
||||||
{
|
{
|
||||||
|
ExitThread (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -344,7 +344,7 @@ public:
|
|||||||
pthread ();
|
pthread ();
|
||||||
virtual ~pthread ();
|
virtual ~pthread ();
|
||||||
|
|
||||||
static void initMainThread(pthread *, HANDLE);
|
static void initMainThread (bool);
|
||||||
static bool isGoodObject(pthread_t const *);
|
static bool isGoodObject(pthread_t const *);
|
||||||
static void atforkprepare();
|
static void atforkprepare();
|
||||||
static void atforkparent();
|
static void atforkparent();
|
||||||
@ -387,10 +387,12 @@ private:
|
|||||||
void pop_all_cleanup_handlers (void);
|
void pop_all_cleanup_handlers (void);
|
||||||
void precreate (pthread_attr *);
|
void precreate (pthread_attr *);
|
||||||
void postcreate ();
|
void postcreate ();
|
||||||
void setThreadIdtoCurrent();
|
void setThreadIdtoCurrent ();
|
||||||
static void setTlsSelfPointer(pthread *);
|
static void setTlsSelfPointer (pthread *);
|
||||||
|
static pthread *getTlsSelfPointer ();
|
||||||
void cancel_self ();
|
void cancel_self ();
|
||||||
DWORD getThreadId ();
|
DWORD getThreadId ();
|
||||||
|
void initCurrentThread ();
|
||||||
};
|
};
|
||||||
|
|
||||||
class pthreadNull : public pthread
|
class pthreadNull : public pthread
|
||||||
@ -493,17 +495,12 @@ class MTinterface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// General
|
// General
|
||||||
DWORD reent_index;
|
|
||||||
DWORD thread_self_dwTlsIndex;
|
|
||||||
/* we may get 0 for the Tls index.. grrr */
|
|
||||||
int indexallocated;
|
|
||||||
int concurrency;
|
int concurrency;
|
||||||
long int threadcount;
|
long int threadcount;
|
||||||
|
|
||||||
// Used for main thread data, and sigproc thread
|
// Used for main thread data, and sigproc thread
|
||||||
struct __reent_t reents;
|
struct __reent_t reents;
|
||||||
struct _winsup_t winsup_reent;
|
struct _winsup_t winsup_reent;
|
||||||
pthread mainthread;
|
|
||||||
|
|
||||||
callback *pthread_prepare;
|
callback *pthread_prepare;
|
||||||
callback *pthread_child;
|
callback *pthread_child;
|
||||||
@ -514,18 +511,25 @@ public:
|
|||||||
class pthread_cond * conds;
|
class pthread_cond * conds;
|
||||||
class semaphore * semaphores;
|
class semaphore * semaphores;
|
||||||
|
|
||||||
|
pthread_key reent_key;
|
||||||
|
pthread_key thread_self_key;
|
||||||
|
|
||||||
void Init (int);
|
void Init (int);
|
||||||
void fixup_before_fork (void);
|
void fixup_before_fork (void);
|
||||||
void fixup_after_fork (void);
|
void fixup_after_fork (void);
|
||||||
|
|
||||||
MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
|
MTinterface () :
|
||||||
|
concurrency (0), threadcount (1),
|
||||||
|
pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL),
|
||||||
|
mutexs (NULL), conds (NULL), semaphores (NULL),
|
||||||
|
reent_key (NULL), thread_self_key (NULL)
|
||||||
{
|
{
|
||||||
pthread_prepare = NULL;
|
|
||||||
pthread_child = NULL;
|
|
||||||
pthread_parent = NULL;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define MT_INTERFACE user_data->threadinterface
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
int __pthread_attr_init (pthread_attr_t * attr);
|
int __pthread_attr_init (pthread_attr_t * attr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user