summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-11-18 14:54:01 +0000
committerRoland McGrath <roland@gnu.org>1995-11-18 14:54:01 +0000
commitd3f649ba551ed42b319f11d3207dd5ad1703ca0c (patch)
tree28dfcad91b83370220a878ad588d1296cf1644c4
parent5636382647c32d771308aaf8d5045d29da6844f3 (diff)
If calling thread is serving an RPC, don't block waiting for that RPC to
finish.
-rw-r--r--libports/inhibit-all-rpcs.c6
-rw-r--r--libports/inhibit-class-rpcs.c17
-rw-r--r--libports/inhibit-port-rpcs.c18
3 files changed, 25 insertions, 16 deletions
diff --git a/libports/inhibit-all-rpcs.c b/libports/inhibit-all-rpcs.c
index ebddbddd..55076486 100644
--- a/libports/inhibit-all-rpcs.c
+++ b/libports/inhibit-all-rpcs.c
@@ -27,13 +27,15 @@ void
ports_inhibit_all_rpcs ()
{
struct port_bucket *bucket;
+ int this_one = 0;
error_t interruptor (void *portstruct)
{
struct port_info *pi = portstruct;
struct rpc_info *rpc;
for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
- hurd_thread_cancel (rpc->thread);
+ if (hurd_thread_cancel (rpc->thread) == EINTR)
+ this_one = 1;
return 0;
}
@@ -42,7 +44,7 @@ ports_inhibit_all_rpcs ()
for (bucket = _ports_all_buckets; bucket; bucket = bucket->next)
ihash_iterate (bucket->htable, interruptor);
- while (_ports_total_rpcs)
+ while (_ports_total_rpcs > this_one)
{
_ports_flags |= _PORTS_INHIBIT_WAIT;
condition_wait (&_ports_block, &_ports_lock);
diff --git a/libports/inhibit-class-rpcs.c b/libports/inhibit-class-rpcs.c
index 033d0b11..5b5a602b 100644
--- a/libports/inhibit-class-rpcs.c
+++ b/libports/inhibit-class-rpcs.c
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 1995 Free Software Foundation, Inc.
Written by Michael I. Bushnell.
@@ -27,23 +27,26 @@ ports_inhibit_class_rpcs (struct port_class *class)
{
struct port_info *pi;
struct rpc_info *rpc;
-
+ int this_one;
+
mutex_lock (&_ports_lock);
-
+
+ this_one = 0;
for (pi = class->ports; pi; pi = pi->next)
for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
- hurd_thread_cancel (rpc->thread);
+ if (hurd_thread_cancel (rpc->thread) == EINTR)
+ this_one = 1;
- while (class->rpcs)
+ while (class->rpcs > this_one)
{
class->flags |= PORT_CLASS_INHIBIT_WAIT;
condition_wait (&_ports_block, &_ports_lock);
}
-
+
class->flags |= PORT_CLASS_INHIBITED;
class->flags &= ~PORT_CLASS_INHIBIT_WAIT;
mutex_unlock (&_ports_lock);
}
-
+
diff --git a/libports/inhibit-port-rpcs.c b/libports/inhibit-port-rpcs.c
index 718a8b3e..f4ddf497 100644
--- a/libports/inhibit-port-rpcs.c
+++ b/libports/inhibit-port-rpcs.c
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 1995 Free Software Foundation, Inc.
Written by Michael I. Bushnell.
@@ -26,19 +26,23 @@ void
ports_inhibit_port_rpcs (void *portstruct)
{
struct port_info *pi = portstruct;
- struct rpc_info *rpc;
-
+ struct rpc_info *rpc, *this_rpc;
+
mutex_lock (&_ports_lock);
+ this_rpc = 0;
for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
- hurd_thread_cancel (rpc->thread);
-
- while (pi->current_rpcs)
+ if (hurd_thread_cancel (rpc->thread) == EINTR)
+ this_rpc = rpc;
+
+ while (pi->current_rpcs
+ /* If this thread's RPC is the only one left, that doesn't count. */
+ && !(pi->current_rpcs == this_rpc && ! this_rpc->next))
{
pi->flags |= PORT_INHIBIT_WAIT;
condition_wait (&_ports_block, &_ports_lock);
}
-
+
pi->flags |= PORT_INHIBITED;
pi->flags &= ~PORT_INHIBIT_WAIT;