This is patch 2 of 3 for MTinterface.
It will convert the TLS handling for reents and thread self pointer to use
the fork save pthread keys. This is important for forks from threads other
than the main thread.
2002-09-24 Thomas Pfaff <[EMAIL PROTECTED]>
* init.cc (dll_entry): Change reents initialization.
* thread.cc (MT_INTERFACE): Move to "thread.h".
(_reent_clib): Use new reents handling.
(_reent_winsup): Ditto.
(MTinterface::Init): Remove member variables initialization.
They are now initialized via constructor. Initialize TLS only
when process is not forked.
(MTinterface::doInit): Implement. Initialize TLS for reents and
thread self pointer.
(MTinterface::fixup_after_fork); Reset threadcount to 1.
Initialize thread self pointer.
(pthread::self): Rename temp to thread. Initialize thread self
pointer if uninitialized.
(pthread::setTlsSelfPointer): Use new thread self handling.
(pthread::thread_init_wrapper): Use new reents handling.
* thread.h (MTinterface::reent_index): Remove.
(MTinterface::thread_self_dwTlsIndex): Ditto.
(MTinterface::indexallocated): Ditto.
(MTinterface::reent_key): New member.
(MTinterface::thread_self_key): Ditto.
(MTinterface::MTinterface): Initialize all members.
(MT_INTERFACE): Move from "thread.cc".
diff -urp src.old/winsup/cygwin/init.cc src/winsup/cygwin/init.cc
--- src.old/winsup/cygwin/init.cc Sun Sep 22 21:11:38 2002
+++ src/winsup/cygwin/init.cc Tue Sep 24 11:12:59 2002
@@ -25,12 +25,8 @@ WINAPI dll_entry (HANDLE h, DWORD reason
dynamically_loaded = (static_load == NULL);
break;
case DLL_THREAD_ATTACH:
- if (user_data->threadinterface)
- {
- if (!TlsSetValue (user_data->threadinterface->reent_index,
- &user_data->threadinterface->reents))
- api_fatal ("Sig proc MT init failed\n");
- }
+ if (MT_INTERFACE->reent_key.set (&MT_INTERFACE->reents))
+ api_fatal("Sig proc MT init failed\n");
break;
case DLL_PROCESS_DETACH:
break;
diff -urp src.old/winsup/cygwin/thread.cc src/winsup/cygwin/thread.cc
--- src.old/winsup/cygwin/thread.cc Tue Sep 24 10:57:31 2002
+++ src/winsup/cygwin/thread.cc Tue Sep 24 10:58:03 2002
@@ -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,38 +160,22 @@ ResourceLocks::Delete ()
void
MTinterface::Init (int forked)
{
+ if (!forked)
+ {
+ doInit ();
+ }
+ // else: Initializition is done in fixup_after_fork
+}
- reent_index = TlsAlloc ();
+void
+MTinterface::doInit (void)
+{
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);
- }
-
- concurrency = 0;
- threadcount = 1; /*1 current thread when Init occurs.*/
+ reent_key.set (&reents);
mainthread.initMainThread ();
-
- if (forked)
- return;
-
- mutexs = NULL;
- conds = NULL;
- semaphores = NULL;
-
}
void
@@ -210,7 +188,10 @@ MTinterface::fixup_before_fork (void)
void
MTinterface::fixup_after_fork (void)
{
+ threadcount = 1;
+
pthread_key::fixup_after_fork ();
+
pthread_mutex *mutex = mutexs;
debug_printf ("mutexs is %x",mutexs);
while (mutex)
@@ -232,36 +213,40 @@ MTinterface::fixup_after_fork (void)
sem->fixup_after_fork ();
sem = sem->next;
}
+
+ pthread *thread = pthread::self (false);
+ if (thread)
+ thread->initThread ();
+ else
+ doInit ();
}
/* pthread calls */
/* static methods */
pthread *
-pthread::self ()
+pthread::self (const bool auto_init)
{
- pthread *temp = (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
- if (temp)
- return temp;
- temp = new pthread ();
- temp->precreate (NULL);
- if (!temp->magic) {
- delete temp;
+ pthread *thread = (pthread *) MT_INTERFACE->thread_self_key.get ();
+ if (thread || !auto_init)
+ return thread;
+ thread = new pthread ();
+ thread->precreate (NULL);
+ if (!thread->magic) {
+ delete thread;
return pthreadNull::getNullpthread ();
}
- temp->initThread ();
- temp->attr.joinable = PTHREAD_CREATE_DETACHED;
- temp->joiner = temp;
- temp->postcreate ();
+ thread->initThread ();
+ thread->attr.joinable = PTHREAD_CREATE_DETACHED;
+ thread->joiner = thread;
- return temp;
+ return thread;
}
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);
}
@@ -1406,9 +1391,7 @@ 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);
diff -urp src.old/winsup/cygwin/thread.h src/winsup/cygwin/thread.h
--- src.old/winsup/cygwin/thread.h Tue Sep 24 10:57:31 2002
+++ src/winsup/cygwin/thread.h Tue Sep 24 11:06:55 2002
@@ -367,7 +367,7 @@ public:
virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
virtual void pop_cleanup_handler (int const execute);
- static pthread* self ();
+ static pthread* self (const bool auto_init = true);
static void *thread_init_wrapper (void *);
virtual unsigned long getsequence_np();
@@ -489,17 +489,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;
@@ -510,17 +505,26 @@ public:
class pthread_cond * conds;
class semaphore * semaphores;
+ pthread mainthread;
+ pthread_key reent_key;
+ pthread_key thread_self_key;
+
void Init (int);
+ void doInit (void);
+
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),
+ mainthread (), reent_key (NULL), thread_self_key (NULL)
{
- pthread_prepare = NULL;
- pthread_child = NULL;
- pthread_parent = NULL;
}
};
+
+#define MT_INTERFACE user_data->threadinterface
extern "C"
{