summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-07-05 23:47:08 +0000
committerRoland McGrath <roland@gnu.org>1996-07-05 23:47:08 +0000
commite33b438a8456aecf60a661ee75ac5977a7b49815 (patch)
tree4cb110b68bb4ddf7611aba3a5382561535c16d65
parent39d690795a63d66c893ceecf74b910977cdfc8f1 (diff)
downloadglibc-e33b438a8456aecf60a661ee75ac5977a7b49815.tar.gz
glibc-e33b438a8456aecf60a661ee75ac5977a7b49815.tar.xz
glibc-e33b438a8456aecf60a661ee75ac5977a7b49815.zip
Fri Jul 5 12:22:51 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
	* hurd/hurdsig.c (_hurd_internal_post_signal): In case of handled
	signal during critical section doing interruptible RPC, if
	_hurdsig_abort_rpcs wants to change thread state, do thread_set_state
	before thread_resume.  If in critical section, pass 0 for SIGNO to
	_hurdsig_abort_rpcs so rpc is interrupted regardless of SA_RESTART.
-rw-r--r--extra-lib.mk2
-rw-r--r--hurd/hurdsig.c28
2 files changed, 26 insertions, 4 deletions
diff --git a/extra-lib.mk b/extra-lib.mk
index 46eef0381c..e6088943e2 100644
--- a/extra-lib.mk
+++ b/extra-lib.mk
@@ -25,7 +25,7 @@ alltypes-$(lib) := $(foreach o,$(object-suffixes-$(lib)),\
 			     $(objpfx)$(patsubst %,$(libtype$o),\
 			     $(lib:lib%=%)))
 
-ifeq (,$(filter $(lib),extra-libs-others))
+ifeq (,$(filter $(lib),$(extra-libs-others)))
 lib-noranlib: $(alltypes-$(lib))
 ifeq (yes,$(build-shared))
 lib-noranlib: $(objpfx)$(lib).so$($(lib).so-version)
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index a3ec24e9e6..1da3fa580d 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -802,19 +802,41 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 	  }
 	else
 	  {
+	    int crit = __spin_lock_locked (&ss->critical_section_lock);
+
 	    wait_for_reply
-	      = (_hurdsig_abort_rpcs (ss, signo, 1,
+	      = (_hurdsig_abort_rpcs (ss,
+				      /* In a critical section, any RPC
+					 should be cancelled instead of
+					 restarted, regardless of
+					 SA_RESTART, so the the entire
+					 "atomic" operation can be aborted
+					 as a unit.  */
+				      crit ? 0 : signo, 1,
 				      &thread_state, &state_changed,
 				      &reply)
 		 != MACH_PORT_NULL);
 
-	    if (__spin_lock_locked (&ss->critical_section_lock))
+	    if (crit)
 	      {
 		/* The thread is in a critical section.  Mark the signal as
 		   pending.  When it finishes the critical section, it will
 		   check for pending signals.  */
 		mark_pending ();
-		assert (! state_changed);
+		if (state_changed)
+		  /* Some cases of interrupting an RPC must change the
+		     thread state to back out the call.  Normally this
+		     change is rolled into the warping to the handler and
+		     sigreturn, but we are not running the handler now
+		     because the thread is in a critical section.  Instead,
+		     mutate the thread right away for the RPC interruption
+		     and resume it; the RPC will return early so the
+		     critical section can end soon.  */
+		  __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
+				      (natural_t *) &thread_state.basic,
+				      MACHINE_THREAD_STATE_COUNT);
+		/* */
+		ss->intr_port = MACH_PORT_NULL;
 		__thread_resume (ss->thread);
 		break;
 	      }