aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <rbtcollins@hotmail.com>2002-11-24 13:54:14 +0000
committerRobert Collins <rbtcollins@hotmail.com>2002-11-24 13:54:14 +0000
commitf8c8e13b7e16dba8c04adc6912a0610292488656 (patch)
treed4595038845d61fb3fe6c3d54b255068ca38a90c
parent4f0de34d3747d689cc741f045072486b0c602f15 (diff)
downloadnewlib-f8c8e13b7e16dba8c04adc6912a0610292488656.zip
newlib-f8c8e13b7e16dba8c04adc6912a0610292488656.tar.gz
newlib-f8c8e13b7e16dba8c04adc6912a0610292488656.tar.bz2
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.
-rw-r--r--winsup/cygwin/ChangeLog37
-rw-r--r--winsup/cygwin/dcrt0.cc2
-rw-r--r--winsup/cygwin/init.cc6
-rw-r--r--winsup/cygwin/thread.cc115
-rw-r--r--winsup/cygwin/thread.h28
5 files changed, 110 insertions, 78 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index df099b0..a6eeef1 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>
* wait.cc (wait4): Force pending signal delivery before waiting for
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 22899e4..6c6acbd 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -628,6 +628,8 @@ dll_crt0_1 ()
ProtectHandle (hMainThread);
cygthread::init ();
+ pthread::initMainThread (!user_data->forkee);
+
/* Initialize debug muto, if DLL is built with --enable-debugging.
Need to do this before any helper threads start. */
debug_init ();
diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc
index 3114293..f740dce 100644
--- a/winsup/cygwin/init.cc
+++ b/winsup/cygwin/init.cc
@@ -27,12 +27,8 @@ WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load)
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
- if (user_data->threadinterface)
- {
- if (!TlsSetValue (user_data->threadinterface->reent_index,
- &user_data->threadinterface->reents))
+ if (MT_INTERFACE->reent_key.set (&MT_INTERFACE->reents))
api_fatal ("thread initialization failed");
- }
break;
case DLL_THREAD_DETACH:
/* not invoked */;
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index e2fc0af..b77a2e5 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -46,35 +46,29 @@ details. */
extern int threadsafe;
-#define MT_INTERFACE user_data->threadinterface
-
struct _reent *
_reent_clib ()
{
- int tmp = GetLastError ();
struct __reent_t *_r =
- (struct __reent_t *) TlsGetValue (MT_INTERFACE->reent_index);
+ (struct __reent_t *) MT_INTERFACE->reent_key.get ();
#ifdef _CYG_THREAD_FAILSAFE
if (_r == 0)
system_printf ("local thread storage not inited");
#endif
-
- SetLastError (tmp);
return _r->_clib;
}
struct _winsup_t *
_reent_winsup ()
{
- int tmp = GetLastError ();
- struct __reent_t *_r;
- _r = (struct __reent_t *) TlsGetValue (MT_INTERFACE->reent_index);
+ struct __reent_t *_r =
+ (struct __reent_t *) MT_INTERFACE->reent_key.get ();
+
#ifdef _CYG_THREAD_FAILSAFE
if (_r == 0)
system_printf ("local thread storage not inited");
#endif
- SetLastError (tmp);
return _r->_winsup;
}
@@ -166,39 +160,14 @@ ResourceLocks::Delete ()
void
MTinterface::Init (int forked)
{
-
- reent_index = TlsAlloc ();
reents._clib = _impure_ptr;
reents._winsup = &winsup_reent;
-
winsup_reent._process_logmask = LOG_UPTO (LOG_DEBUG);
- TlsSetValue (reent_index, &reents);
- // the static reent_data will be used in the main thread
-
- 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);
- }
+ if (!forked)
+ reent_key.set (&reents);
- concurrency = 0;
- threadcount = 1; /* 1 current thread when Init occurs.*/
-
- pthread::initMainThread (&mainthread, myself->hProcess);
pthread_mutex::initMutex ();
-
- if (forked)
- return;
-
- mutexs = NULL;
- conds = NULL;
- semaphores = NULL;
-
}
void
@@ -233,40 +202,51 @@ MTinterface::fixup_after_fork (void)
sem->fixup_after_fork ();
sem = sem->next;
}
+
+ pthread::initMainThread (true);
+
+ threadcount = 1;
}
/* pthread calls */
/* static methods */
void
-pthread::initMainThread (pthread *mainThread, HANDLE win32_obj_id)
+pthread::initMainThread (bool do_init)
{
- mainThread->win32_obj_id = win32_obj_id;
- mainThread->setThreadIdtoCurrent ();
- setTlsSelfPointer (mainThread);
+ if (!do_init)
+ return;
+
+ pthread *thread = getTlsSelfPointer ();
+ if (!thread)
+ {
+ thread = new pthread ();
+ if (!thread)
+ api_fatal ("failed to create mainthread object");
+ }
+
+ thread->initCurrentThread ();
}
pthread *
pthread::self ()
{
- 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;
+ pthread *thread = getTlsSelfPointer ();
+ if (thread)
+ return thread;
+ return pthreadNull::getNullpthread ();
}
void
pthread::setTlsSelfPointer (pthread *thisThread)
{
- /* the OS doesn't check this for <= 64 Tls entries (pre win2k) */
- TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thisThread);
+ MT_INTERFACE->thread_self_key.set (thisThread);
+}
+
+pthread *
+pthread::getTlsSelfPointer ()
+{
+ return (pthread *) MT_INTERFACE->thread_self_key.get ();
}
@@ -384,9 +364,6 @@ pthread::exit (void *value_ptr)
mutex.UnLock ();
}
- /* Prevent DLL_THREAD_DETACH Attempting to clean us up */
- setTlsSelfPointer (0);
-
if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
::exit (0);
else
@@ -715,6 +692,18 @@ pthread::getThreadId ()
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 */
bool
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);
- /* This is not checked by the OS !! */
- if (!TlsSetValue (MT_INTERFACE->reent_index, &local_reent))
- system_printf ("local storage for thread couldn't be set");
+ MT_INTERFACE->reent_key.set (&local_reent);
+ thread->setThreadIdtoCurrent ();
setTlsSelfPointer (thread);
thread->mutex.Lock ();
// if thread is detached force cleanup on exit
if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
- thread->joiner = pthread::self ();
+ thread->joiner = thread;
thread->mutex.UnLock ();
#ifdef _CYG_THREAD_FAILSAFE
@@ -1787,6 +1775,9 @@ pthread::join (pthread_t *thread, void **return_val)
{
pthread_t joiner = self ();
+ if (!isGoodObject (&joiner))
+ return EINVAL;
+
// Initialize return val with NULL
if (return_val)
*return_val = NULL;
@@ -2594,6 +2585,7 @@ pthreadNull::getNullpthread ()
pthreadNull::pthreadNull ()
{
+ attr.joinable = PTHREAD_CREATE_DETACHED;
/* Mark ourselves as invalid */
magic = 0;
}
@@ -2610,6 +2602,7 @@ pthreadNull::create (void *(*)(void *), pthread_attr *, void *)
void
pthreadNull::exit (void *value_ptr)
{
+ ExitThread (0);
}
int
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index 73e57ed..32175a4 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -344,7 +344,7 @@ public:
pthread ();
virtual ~pthread ();
- static void initMainThread(pthread *, HANDLE);
+ static void initMainThread (bool);
static bool isGoodObject(pthread_t const *);
static void atforkprepare();
static void atforkparent();
@@ -387,10 +387,12 @@ private:
void pop_all_cleanup_handlers (void);
void precreate (pthread_attr *);
void postcreate ();
- void setThreadIdtoCurrent();
- static void setTlsSelfPointer(pthread *);
+ void setThreadIdtoCurrent ();
+ static void setTlsSelfPointer (pthread *);
+ static pthread *getTlsSelfPointer ();
void cancel_self ();
DWORD getThreadId ();
+ void initCurrentThread ();
};
class pthreadNull : public pthread
@@ -493,17 +495,12 @@ class MTinterface
{
public:
// General
- DWORD reent_index;
- DWORD thread_self_dwTlsIndex;
- /* we may get 0 for the Tls index.. grrr */
- int indexallocated;
int concurrency;
long int threadcount;
// Used for main thread data, and sigproc thread
struct __reent_t reents;
struct _winsup_t winsup_reent;
- pthread mainthread;
callback *pthread_prepare;
callback *pthread_child;
@@ -514,18 +511,25 @@ public:
class pthread_cond * conds;
class semaphore * semaphores;
+ pthread_key reent_key;
+ pthread_key thread_self_key;
+
void Init (int);
void fixup_before_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"
{
int __pthread_attr_init (pthread_attr_t * attr);