* cygheap.cc (init_cygheap::init_tls_list): Accommodate threadlist

having a new type threadlist_t *.  Convert commented out code into an
	#if 0.  Create thread mutex.  Explain why.
	(init_cygheap::remove_tls): Drop timeout value.  Always wait infinitely
	for tls_sentry.  Return mutex HANDLE of just deleted threadlist entry.
	(init_cygheap::find_tls): New implementation taking tls pointer as
	search parameter.  Return threadlist_t *.
	(init_cygheap::find_tls): Return threadlist_t *.  Define ix as auto
	variable.  Drop exception handling since crash must be made impossible
	due to correct synchronization.  Return with locked mutex.
	* cygheap.h (struct threadlist_t): Define.
	(struct init_cygheap): Convert threadlist to threadlist_t type.
	(init_cygheap::remove_tls): Align declaration to above change.
	(init_cygheap::find_tls): Ditto.
	(init_cygheap::unlock_tls): Define.
	* cygtls.cc (_cygtls::remove): Unlock and close mutex when finishing.
	* exceptions.cc (sigpacket::process): Lock _cygtls area of thread before
	accessing it.
	* fhandler_termios.cc (fhandler_termios::bg_check): Ditto.
	* sigproc.cc (sig_send): Ditto.
	* thread.cc (pthread::exit): Ditto.  Add comment.
	(pthread::cancel): Ditto.
This commit is contained in:
Corinna Vinschen
2014-11-28 20:46:13 +00:00
parent c2f50c4099
commit 26158dc3e9
8 changed files with 200 additions and 67 deletions

View File

@ -515,7 +515,7 @@ void
pthread::exit (void *value_ptr)
{
class pthread *thread = this;
bool is_main_tls = (cygtls == _main_tls); // Check cygtls before deleting this
_cygtls *tls = cygtls; /* Save cygtls before deleting this. */
// run cleanup handlers
pop_all_cleanup_handlers ();
@ -541,15 +541,16 @@ pthread::exit (void *value_ptr)
::exit (0);
else
{
if (is_main_tls)
if (tls == _main_tls)
{
/* FIXME: Needs locking. */
cygheap->find_tls (tls); /* Lock _main_tls mutex. */
_cygtls *dummy = (_cygtls *) malloc (sizeof (_cygtls));
*dummy = *_main_tls;
_main_tls = dummy;
_main_tls->initialized = 0;
}
cygtls->remove (INFINITE);
/* This also unlocks and closes the _main_tls mutex. */
tls->remove (INFINITE);
ExitThread (0);
}
}
@ -595,6 +596,7 @@ pthread::cancel ()
and tends to hang infinitely if we change the instruction pointer.
So just don't cancel asynchronously if the thread is currently
executing Windows code. Rely on deferred cancellation in this case. */
threadlist_t *tl_entry = cygheap->find_tls (cygtls);
if (!cygtls->inside_kernel (&context))
{
#ifdef __x86_64__
@ -604,6 +606,7 @@ pthread::cancel ()
#endif
SetThreadContext (win32_obj_id, &context);
}
cygheap->unlock_tls (tl_entry);
}
mutex.unlock ();
/* See above. For instance, a thread which waits for a semaphore in sem_wait