* DevNotes: Add entry cgf-000014.
* cygheap.cc (tls_sentry): Move here, rename from 'sentry' in cygtls.cc (tls_sentry::lock): Ditto. (nthreads): Move from cygtls.cc (THREADLIST_CHUNK): Ditto. (cygheap_init): Call init_tls_list(). (init_cygheap::init_tls_list): Define new function. (init_cygheap::add_tls): Ditto. (init_cygheap::remove_tls): Ditto. (init_cygheap::find_tls): Ditto. Semi-resurrect from _cygtls::find_tls. * cygheap.h (init_cygheap::init_tls_list): Declare new function. (init_cygheap::add_tls): Ditto. (init_cygheap::remove_tls): Ditto. (init_cygheap::find_tls): Ditto. * cygtls.cc (sentry): Delete. (sentry::lock): Ditto. (nthreads): Ditto. (THREADLIST_CHUNK): Ditto. (_cygtls::init): Delete definition. (_cygtls::init_thread): Call cygheap->add_tls() to add thread to global list. (_cygtls::remove): cygheap->remove_tls() to remove thread from global list. * cygtls.h (_cygtls::init): Delete declaration. * dcrt0.cc (dll_crt0_0): Delete call to _cygtls::init(). * exceptions.cc (sigpacket::process): When no thread is specified, try to find one via cygheap->find_tls.
This commit is contained in:
		| @@ -1,3 +1,34 @@ | ||||
| 2012-08-09  Christopher Faylor  <me.cygwin2012@cgf.cx> | ||||
|  | ||||
| 	* DevNotes: Add entry cgf-000014. | ||||
| 	* cygheap.cc (tls_sentry): Move here, rename from 'sentry' in cygtls.cc | ||||
| 	(tls_sentry::lock): Ditto. | ||||
| 	(nthreads): Move from cygtls.cc | ||||
| 	(THREADLIST_CHUNK): Ditto. | ||||
| 	(cygheap_init): Call init_tls_list(). | ||||
| 	(init_cygheap::init_tls_list): Define new function. | ||||
| 	(init_cygheap::add_tls): Ditto. | ||||
| 	(init_cygheap::remove_tls): Ditto. | ||||
| 	(init_cygheap::find_tls): Ditto.  Semi-resurrect from | ||||
| 	_cygtls::find_tls. | ||||
| 	* cygheap.h (init_cygheap::init_tls_list): Declare new function. | ||||
| 	(init_cygheap::add_tls): Ditto. | ||||
| 	(init_cygheap::remove_tls): Ditto. | ||||
| 	(init_cygheap::find_tls): Ditto. | ||||
| 	* cygtls.cc (sentry): Delete. | ||||
| 	(sentry::lock): Ditto. | ||||
| 	(nthreads): Ditto. | ||||
| 	(THREADLIST_CHUNK): Ditto. | ||||
| 	(_cygtls::init): Delete definition. | ||||
| 	(_cygtls::init_thread): Call cygheap->add_tls() to add thread to global | ||||
| 	list. | ||||
| 	(_cygtls::remove): cygheap->remove_tls() to remove thread from global | ||||
| 	list. | ||||
| 	* cygtls.h (_cygtls::init): Delete declaration. | ||||
| 	* dcrt0.cc (dll_crt0_0): Delete call to _cygtls::init(). | ||||
| 	* exceptions.cc (sigpacket::process): When no thread is specified, try | ||||
| 	to find one via cygheap->find_tls. | ||||
|  | ||||
| 2012-08-08  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* include/sys/wait.h (_wait): Define when building newlib. | ||||
|   | ||||
| @@ -1,3 +1,16 @@ | ||||
| 2012-08-09  cgf-000014 | ||||
|  | ||||
| So, apparently I got it somewhat right before wrt signal handling. | ||||
| Checking on linux, it appears that signals will be sent to a thread | ||||
| which can accept the signal.  So resurrecting and extending the | ||||
| "find_tls" function is in order.  This function will return the tls | ||||
| of any thread which 1) is waiting for a signal with sigwait*() or | ||||
| 2) has the signal unmasked. | ||||
|  | ||||
| In redoing this it became obvious that I had the class designation wrong | ||||
| for the threadlist handling so I moved the manipulation of the global | ||||
| threadlist into the cygheap where it logically belongs. | ||||
|  | ||||
| 2012-07-21  cgf-000013 | ||||
|  | ||||
| These changes reflect a revamp of the "wait for signal" functionality | ||||
|   | ||||
| @@ -47,6 +47,23 @@ struct cygheap_entry | ||||
|   char data[0]; | ||||
| }; | ||||
|  | ||||
| class tls_sentry | ||||
| { | ||||
| public: | ||||
|   static muto lock; | ||||
|   int destroy; | ||||
|   void init (); | ||||
|   bool acquired () {return lock.acquired ();} | ||||
|   tls_sentry () {destroy = 0;} | ||||
|   tls_sentry (DWORD wait) {destroy = lock.acquire (wait);} | ||||
|   ~tls_sentry () {if (destroy) lock.release ();} | ||||
| }; | ||||
|  | ||||
| muto NO_COPY tls_sentry::lock; | ||||
| static NO_COPY size_t nthreads; | ||||
|  | ||||
| #define THREADLIST_CHUNK 256 | ||||
|  | ||||
| #define NBUCKETS (sizeof (cygheap->buckets) / sizeof (cygheap->buckets[0])) | ||||
| #define N0 ((_cmalloc_entry *) NULL) | ||||
| #define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (unsigned) (N0->data))) | ||||
| @@ -256,6 +273,7 @@ cygheap_init () | ||||
|     cygheap->fdtab.init (); | ||||
|   if (!cygheap->sigs) | ||||
|     sigalloc (); | ||||
|   cygheap->init_tls_list (); | ||||
| } | ||||
|  | ||||
| /* Copyright (C) 1997, 2000 DJ Delorie */ | ||||
| @@ -545,3 +563,84 @@ cygheap_user::set_name (const char *new_name) | ||||
|   cfree_and_set (pdomain); | ||||
|   cfree_and_set (pwinname); | ||||
| } | ||||
|  | ||||
| void | ||||
| init_cygheap::init_tls_list () | ||||
| { | ||||
|   if (threadlist) | ||||
|     memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0])); | ||||
|   else | ||||
|     { | ||||
|       sthreads = THREADLIST_CHUNK; | ||||
|       threadlist = (_cygtls **) ccalloc_abort (HEAP_TLS, cygheap->sthreads, | ||||
| 					       sizeof (cygheap->threadlist[0])); | ||||
|     } | ||||
|   tls_sentry::lock.init ("thread_tls_sentry"); | ||||
| } | ||||
|  | ||||
| void | ||||
| init_cygheap::add_tls (_cygtls *t) | ||||
| { | ||||
|   cygheap->user.reimpersonate (); | ||||
|   tls_sentry here (INFINITE); | ||||
|   if (nthreads >= cygheap->sthreads) | ||||
|     { | ||||
|       threadlist = (_cygtls **) | ||||
| 	crealloc_abort (threadlist, (sthreads += THREADLIST_CHUNK) | ||||
| 			* sizeof (threadlist[0])); | ||||
|       // memset (threadlist + nthreads, 0, THREADLIST_CHUNK * sizeof (threadlist[0])); | ||||
|     } | ||||
|  | ||||
|   threadlist[nthreads++] = t; | ||||
| } | ||||
|  | ||||
| void | ||||
| init_cygheap::remove_tls (_cygtls *t, DWORD wait) | ||||
| { | ||||
|   tls_sentry here (wait); | ||||
|   if (here.acquired ()) | ||||
|     { | ||||
|       for (size_t i = 0; i < nthreads; i++) | ||||
| 	if (t == threadlist[i]) | ||||
| 	  { | ||||
| 	    if (i < --nthreads) | ||||
| 	      threadlist[i] = threadlist[nthreads]; | ||||
| 	    debug_only_printf ("removed %p element %d", this, i); | ||||
| 	    break; | ||||
| 	  } | ||||
|     } | ||||
| } | ||||
|  | ||||
| _cygtls * | ||||
| init_cygheap::find_tls (int sig) | ||||
| { | ||||
|   debug_printf ("sig %d\n", sig); | ||||
|   tls_sentry here (INFINITE); | ||||
|  | ||||
|   static int NO_COPY threadlist_ix; | ||||
|  | ||||
|   _cygtls *t = _main_tls; | ||||
|  | ||||
|   myfault efault; | ||||
|   if (efault.faulted ()) | ||||
|     threadlist[threadlist_ix]->remove (INFINITE); | ||||
|   else | ||||
|     { | ||||
|       threadlist_ix = -1; | ||||
|       while (++threadlist_ix < (int) nthreads) | ||||
| 	if (sigismember (&(threadlist[threadlist_ix]->sigwait_mask), sig)) | ||||
| 	  { | ||||
| 	    t = cygheap->threadlist[threadlist_ix]; | ||||
| 	    goto out; | ||||
| 	  } | ||||
|       threadlist_ix = -1; | ||||
|       while (++threadlist_ix < (int) nthreads) | ||||
| 	if (!sigismember (&(threadlist[threadlist_ix]->sigmask), sig)) | ||||
| 	  { | ||||
| 	    t = cygheap->threadlist[threadlist_ix]; | ||||
| 	    break; | ||||
| 	  } | ||||
|     } | ||||
| out: | ||||
|   return t; | ||||
| } | ||||
|   | ||||
| @@ -396,6 +396,10 @@ struct init_cygheap: public mini_cygheap | ||||
|   hook_chain hooks; | ||||
|   void close_ctty (); | ||||
|   void init_installation_root (); | ||||
|   void init_tls_list () __attribute__ ((regparm (1)));; | ||||
|   void add_tls (_cygtls *) __attribute__ ((regparm (2))); | ||||
|   void remove_tls (_cygtls *, DWORD) __attribute__ ((regparm (3))); | ||||
|   _cygtls *find_tls (int) __attribute__ ((regparm (2))); | ||||
| }; | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -19,39 +19,6 @@ details. */ | ||||
| #include "sigproc.h" | ||||
| #include "exception.h" | ||||
|  | ||||
| class sentry | ||||
| { | ||||
|   static muto lock; | ||||
|   int destroy; | ||||
| public: | ||||
|   void init (); | ||||
|   bool acquired () {return lock.acquired ();} | ||||
|   sentry () {destroy = 0;} | ||||
|   sentry (DWORD wait) {destroy = lock.acquire (wait);} | ||||
|   ~sentry () {if (destroy) lock.release ();} | ||||
|   friend void _cygtls::init (); | ||||
| }; | ||||
|  | ||||
| muto NO_COPY sentry::lock; | ||||
|  | ||||
| static size_t NO_COPY nthreads; | ||||
|  | ||||
| #define THREADLIST_CHUNK 256 | ||||
|  | ||||
| void | ||||
| _cygtls::init () | ||||
| { | ||||
|   if (cygheap->threadlist) | ||||
|     memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0])); | ||||
|   else | ||||
|     { | ||||
|       cygheap->sthreads = THREADLIST_CHUNK; | ||||
|       cygheap->threadlist = (_cygtls **) ccalloc_abort (HEAP_TLS, cygheap->sthreads, | ||||
| 							sizeof (cygheap->threadlist[0])); | ||||
|     } | ||||
|   sentry::lock.init ("sentry_lock"); | ||||
| } | ||||
|  | ||||
| /* Two calls to get the stack right... */ | ||||
| void | ||||
| _cygtls::call (DWORD (*func) (void *, void *), void *arg) | ||||
| @@ -167,18 +134,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *)) | ||||
|       || (void *) func == (void *) cygthread::simplestub) | ||||
|     return; | ||||
|  | ||||
|   cygheap->user.reimpersonate (); | ||||
|  | ||||
|   sentry here (INFINITE); | ||||
|   if (nthreads >= cygheap->sthreads) | ||||
|     { | ||||
|       cygheap->threadlist = (_cygtls **) | ||||
| 	crealloc_abort (cygheap->threadlist, (cygheap->sthreads += THREADLIST_CHUNK) | ||||
| 			* sizeof (cygheap->threadlist[0])); | ||||
|       memset (cygheap->threadlist + nthreads, 0, THREADLIST_CHUNK * sizeof (cygheap->threadlist[0])); | ||||
|     } | ||||
|  | ||||
|   cygheap->threadlist[nthreads++] = this; | ||||
|   cygheap->add_tls (this); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -237,22 +193,7 @@ _cygtls::remove (DWORD wait) | ||||
|   free_local (hostent_buf); | ||||
|   /* Free temporary TLS path buffers. */ | ||||
|   locals.pathbufs.destroy (); | ||||
|  | ||||
|   do | ||||
|     { | ||||
|       sentry here (wait); | ||||
|       if (here.acquired ()) | ||||
| 	{ | ||||
| 	  for (size_t i = 0; i < nthreads; i++) | ||||
| 	    if (this == cygheap->threadlist[i]) | ||||
| 	      { | ||||
| 		if (i < --nthreads) | ||||
| 		  cygheap->threadlist[i] = cygheap->threadlist[nthreads]; | ||||
| 		debug_printf ("removed %p element %d", this, i); | ||||
| 		break; | ||||
| 	      } | ||||
| 	} | ||||
|     } while (0); | ||||
|   cygheap->remove_tls (this, wait); | ||||
|   remove_wq (wait); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -204,7 +204,6 @@ public: | ||||
|   unsigned initialized; | ||||
|  | ||||
|   /*gentls_offsets*/ | ||||
|   static void init (); | ||||
|   void init_thread (void *, DWORD (*) (void *, void *)); | ||||
|   static void call (DWORD (*) (void *, void *), void *); | ||||
|   void remove (DWORD); | ||||
|   | ||||
| @@ -773,8 +773,6 @@ dll_crt0_0 () | ||||
|  | ||||
|   user_data->threadinterface->Init (); | ||||
|  | ||||
|   _cygtls::init (); | ||||
|  | ||||
|   _main_tls = &_my_tls; | ||||
|  | ||||
|   /* Initialize signal processing here, early, in the hopes that the creation | ||||
|   | ||||
| @@ -1170,8 +1170,8 @@ sigpacket::process () | ||||
|     sigproc_printf ("using tls %p", tls); | ||||
|   else | ||||
|     { | ||||
|       tls = _main_tls; | ||||
|       sigproc_printf ("using main tls %p", _main_tls); | ||||
|       tls = cygheap->find_tls (si.si_signo); | ||||
|       sigproc_printf ("using tls %p", tls); | ||||
|     } | ||||
|  | ||||
|   if (si.si_signo == SIGKILL) | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| Bug fixes: | ||||
| ---------- | ||||
|  | ||||
| - Revamp signals so that signals-to-threads more closely mimic linux | ||||
| - Revamp signals so that signals-to-threads more closely mimic Linux | ||||
|   operation. | ||||
|   First step of fix for: http://cygwin.com/ml/cygwin/2012-05/msg00186.html | ||||
|   as well as observed Linux behavior. | ||||
|  | ||||
| - Revert to only creating a new session leader when we know that a | ||||
|   console process is started in the background. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user