* cygtls.cc (_cygtls::reset_signal_arrived): New function.
(set_signal_arrived::~set_signal_arrived): Use reset_signal_arrived to reset state. * exceptions.cc (sig_handle_tty_stop): Use WAIT_SIGNALED rather than assume we know the return from cancelable_wait. (_cygtls::interrupt_setup): Modify to allow calling when executing in non-cygwin code via sigdelayed. Always reset signal_arrived. * gendef: Throughout use start_offset rather than the completely wrong sizeof__cygtls. (_sigdelayed): Rewrite to avoid duplication when calling the signal handler. (sigreturn): Delete. * gentls_offsets: Define start_offset rather than sizeof__cygtls. * tlsoffsets.h: Regenerate.
This commit is contained in:
		| @@ -1,3 +1,20 @@ | ||||
| 2012-07-29  Christopher Faylor  <me.cygwin2012@cgf.cx> | ||||
|  | ||||
| 	* cygtls.cc (_cygtls::reset_signal_arrived): New function. | ||||
| 	(set_signal_arrived::~set_signal_arrived): Use reset_signal_arrived to | ||||
| 	reset state. | ||||
| 	* exceptions.cc (sig_handle_tty_stop): Use WAIT_SIGNALED rather than | ||||
| 	assume we know the return from cancelable_wait. | ||||
| 	(_cygtls::interrupt_setup): Modify to allow calling when executing in | ||||
| 	non-cygwin code via sigdelayed.  Always reset signal_arrived. | ||||
| 	* gendef: Throughout use start_offset rather than the completely wrong | ||||
| 	sizeof__cygtls. | ||||
| 	(_sigdelayed): Rewrite to avoid duplication when calling the signal | ||||
| 	handler. | ||||
| 	(sigreturn): Delete. | ||||
| 	* gentls_offsets: Define start_offset rather than sizeof__cygtls. | ||||
| 	* tlsoffsets.h: Regenerate. | ||||
|  | ||||
| 2012-07-29  Christopher Faylor  <me.cygwin2012@cgf.cx> | ||||
|  | ||||
| 	* fhandler_termios.cc (fhandler_termios::line_edit): Use special case | ||||
|   | ||||
| @@ -748,7 +748,7 @@ sig_handle_tty_stop (int sig) | ||||
|   switch (cancelable_wait (sigCONT, cw_infinite, cw_sig_eintr)) | ||||
|     { | ||||
|     case WAIT_OBJECT_0: | ||||
|     case WAIT_OBJECT_0 + 1: | ||||
|     case WAIT_SIGNALED: | ||||
|       myself->stopsig = SIGCONT; | ||||
|       myself->alert_parent (SIGCONT); | ||||
|       break; | ||||
| @@ -801,7 +801,7 @@ _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga) | ||||
|  | ||||
|   this->sig = sig;			// Should always be last thing set to avoid a race | ||||
|  | ||||
|   if (signal_arrived) | ||||
|   if (incyg && signal_arrived) | ||||
|     SetEvent (signal_arrived); | ||||
|  | ||||
|   proc_subproc (PROC_CLEARWAIT, 1); | ||||
| @@ -1259,10 +1259,14 @@ _cygtls::call_signal_handler () | ||||
|   while (1) | ||||
|     { | ||||
|       lock (); | ||||
|       if (sig) | ||||
|       if (!sig) | ||||
| 	{ | ||||
| 	  unlock (); | ||||
| 	  break; | ||||
| 	} | ||||
|  | ||||
|       if (incyg) | ||||
| 	pop (); | ||||
|       else | ||||
| 	break; | ||||
|  | ||||
|       debug_only_printf ("dealing with signal %d", sig); | ||||
|       this_sa_flags = sa_flags; | ||||
| @@ -1272,12 +1276,12 @@ _cygtls::call_signal_handler () | ||||
|       sigset_t this_oldmask = set_process_mask_delta (); | ||||
|       int this_errno = saved_errno; | ||||
|       sig = 0; | ||||
|       reset_signal_arrived (); | ||||
|       unlock ();	// make sure synchronized | ||||
|       if (!(this_sa_flags & SA_SIGINFO)) | ||||
| 	{ | ||||
| 	  void (*sigfunc) (int) = thisfunc; | ||||
| 	  incyg = false; | ||||
| 	  sigfunc (thissig); | ||||
| 	  thisfunc (thissig); | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| @@ -1293,7 +1297,6 @@ _cygtls::call_signal_handler () | ||||
| 	set_errno (this_errno); | ||||
|     } | ||||
|  | ||||
|   unlock (); | ||||
|   return this_sa_flags & SA_RESTART || (this != _main_tls); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -162,60 +162,23 @@ __sigbe:						# return here after cygwin syscall | ||||
|  | ||||
| 	.global	_sigdelayed | ||||
| _sigdelayed: | ||||
| 	pushl	%ebp | ||||
| 	movl	%esp,%ebp | ||||
| 	pushl   %ebp | ||||
| 	movl    %esp,%ebp | ||||
| 	pushf | ||||
| 	pushl	%esi | ||||
| 	pushl	%edi | ||||
| 	pushl	%edx | ||||
| 	pushl	%ecx | ||||
| 	pushl	%ebx | ||||
| 	pushl	%eax | ||||
| 	movl	%fs:4,%ebx | ||||
| 1:	movl	\$1,%eax | ||||
| 	xchgl	%eax,$tls::stacklock(%ebx) | ||||
| 	movl	%eax,$tls::spinning(%ebx) # flag if we are waiting for lock | ||||
| 					  # If %eax is 1 then someone else has | ||||
| 					  # the lock but we want to flag that | ||||
| 					  # we're waiting for it.  If %eax is 0 | ||||
| 					  # then we're not spinning and 0 will | ||||
| 					  # reflect that. | ||||
| 	testl	%eax,%eax | ||||
| 	jz	2f | ||||
| 	call	_yield | ||||
| 	jmp	1b | ||||
| 2:	incl	$tls::incyg(%ebx) | ||||
| 	movl	$tls::sig(%ebx),%eax | ||||
| 	testl	%eax,%eax | ||||
| 	jz	leave			# call_signal_handler may have beat us | ||||
| 					# to it | ||||
| 	pushl	$tls::saved_errno(%ebx)	# saved errno | ||||
| 	call	_set_process_mask_delta | ||||
| 	pushl	%eax | ||||
| 	pushl   %esi | ||||
| 	pushl   %edi | ||||
| 	pushl   %edx | ||||
| 	pushl   %ecx | ||||
| 	pushl   %ebx | ||||
| 	pushl   %eax | ||||
| 	movl	%fs:4,%ebx				# get tls | ||||
| 	pushl   $tls::saved_errno(%ebx) # saved errno | ||||
|  | ||||
| 	# fill out handler arguments | ||||
| 	xorl	%eax,%eax		# ucontext_t (currently not set) | ||||
| 	pushl	%eax | ||||
| 	leal	$tls::infodata(%ebx),%eax | ||||
| 	pushl	%eax			# siginfo | ||||
| 	pushl	$tls::sig(%ebx)		# signal number | ||||
|  | ||||
| 	pushl	\$_sigreturn		# where to return | ||||
| 	pushl	$tls::func(%ebx)	# user-supplied signal func | ||||
| 	movl	\$0,$tls::sig(%ebx)	# zero the signal number as a | ||||
| 					# flag to the signal handler thread | ||||
| 					# that it is ok to set up sigsave | ||||
| 4:	decl	$tls::incyg(%ebx) | ||||
| 	decl	$tls::stacklock(%ebx) | ||||
| 	ret				# return via signal handler | ||||
|  | ||||
| 	.global	_sigreturn | ||||
| _sigreturn: | ||||
| 	movl	%fs:4,%ebx | ||||
| 	incl	$tls::incyg(%ebx) | ||||
| 	addl	\$12,%esp				# remove arguments | ||||
| 	call	_set_process_mask\@4 | ||||
| 	movl	\$$tls::start_offset,%eax		# point to beginning | ||||
| 	addl	%ebx,%eax				#  of tls block | ||||
| 	call	__ZN7_cygtls19call_signal_handlerEv	# call handler | ||||
|  | ||||
| 	movl	%fs:4,%ebx				# reget tls | ||||
| 1:	movl	\$1,%eax				# potential lock value | ||||
| 	xchgl	%eax,$tls::stacklock(%ebx)		# see if we can grab it | ||||
| 	movl	%eax,$tls::spinning(%ebx)		# flag if we are waiting for lock | ||||
| @@ -292,7 +255,7 @@ stabilize_sig_stack: | ||||
| 	cmpl	\$0,$tls::sig(%ebx) | ||||
| 	jz	3f | ||||
| 	decl	$tls::stacklock(%ebx)			# unlock | ||||
| 	movl	\$-$tls::sizeof__cygtls,%eax		# point to beginning | ||||
| 	movl	\$$tls::start_offset,%eax		# point to beginning | ||||
| 	addl	%ebx,%eax				#  of tls block | ||||
| 	call	__ZN7_cygtls19call_signal_handlerEv | ||||
| 	jmp	1b | ||||
|   | ||||
| @@ -60,7 +60,7 @@ main(int argc, char **argv) | ||||
| # define poffset(f) (((char *) &(foo->f)) - ((char *) foo)) | ||||
| EOF | ||||
|     print TMP 'puts ("//;# autogenerated:  Do not edit.\n");', "\n\n"; | ||||
|     print TMP "printf (\"//; \$tls::sizeof_$struct = %d;\\n\", sizeof($struct\));\n"; | ||||
|     print TMP "printf (\"//; \$tls::start_offset = -%d;\\n\", CYGTLS_PADSIZE);\n"; | ||||
|     for my $f (@fields) { | ||||
| 	print TMP '  printf ("//; $tls::', $f, ' = %d;\n", ', "offset($f));\n"; | ||||
| 	print TMP '  printf ("//; $tls::p', $f, ' = %d;\n", ', "poffset($f));\n"; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| //;# autogenerated:  Do not edit. | ||||
|  | ||||
| //; $tls::sizeof__cygtls = 4048; | ||||
| //; $tls::start_offset = -12700; | ||||
| //; $tls::locals = -12700; | ||||
| //; $tls::plocals = 0; | ||||
| //; $tls::local_clib = -11236; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user