summaryrefslogtreecommitdiff
path: root/libports
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1995-06-20 16:31:54 +0000
committerMichael I. Bushnell <mib@gnu.org>1995-06-20 16:31:54 +0000
commita6f82b9d63d88072693024404a981b19a5c1e7eb (patch)
treeb9ecbaa316e21221f18bf3e04fbe39ee6c63dda4 /libports
parentfba5e72c73d8f31cc5324bbed379d5bfe16061fe (diff)
Initial revision
Diffstat (limited to 'libports')
-rw-r--r--libports/allocate-port.c80
-rw-r--r--libports/begin-rpc.c86
-rw-r--r--libports/complete-deallocate.c48
-rw-r--r--libports/count-bucket.c34
-rw-r--r--libports/count-class.c37
-rw-r--r--libports/create-bucket.c47
-rw-r--r--libports/create-class.c38
-rw-r--r--libports/destroy-right.c49
-rw-r--r--libports/enable-bucket.c34
-rw-r--r--libports/enable-class.c34
-rw-r--r--libports/end-rpc.c44
-rw-r--r--libports/get-right.c49
-rw-r--r--libports/inhibit-all-rpcs.c56
-rw-r--r--libports/inhibit-bucket-rpcs.c52
-rw-r--r--libports/inhibit-class-rpcs.c48
-rw-r--r--libports/inhibit-port-rpcs.c45
-rw-r--r--libports/init.c28
-rw-r--r--libports/intern-external-port.c96
-rw-r--r--libports/interrupt-rpcs.c38
-rw-r--r--libports/lookup-port.c52
-rw-r--r--libports/manage-multithread.c123
-rw-r--r--libports/manage-one-thread.c63
-rw-r--r--libports/no-senders.c61
-rw-r--r--libports/port-deref-weak.c38
-rw-r--r--libports/port-deref.c53
-rw-r--r--libports/port-ref-weak.c34
-rw-r--r--libports/port-ref.c36
-rw-r--r--libports/reallocate-from-external.c80
-rw-r--r--libports/reallocate-port.c62
-rw-r--r--libports/resume-all-rpcs.c39
-rw-r--r--libports/resume-bucket-rpcs.c37
-rw-r--r--libports/resume-class-rpcs.c38
-rw-r--r--libports/resume-port-rpcs.c43
33 files changed, 1702 insertions, 0 deletions
diff --git a/libports/allocate-port.c b/libports/allocate-port.c
new file mode 100644
index 00000000..03839635
--- /dev/null
+++ b/libports/allocate-port.c
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <assert.h>
+#include <cthreads.h>
+#include <hurd/ihash.h>
+
+void *ports_allocate_port (struct port_bucket *bucket,
+ size_t size,
+ struct port_class *class)
+{
+ mach_port_t port;
+ error_t err;
+ struct port_info *pi;
+
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &port);
+ assert_perror (err);
+ if (size < sizeof (struct port_info))
+ size = sizeof (struct port_info);
+
+ pi = malloc (size);
+ assert (pi);
+ pi->class = class;
+ pi->refcnt = 1;
+ pi->weakrefcnt = 0;
+ pi->mscount = 0;
+ pi->flags = 0;
+ pi->port_right = port;
+ pi->current_rpcs = 0;
+ pi->bucket = bucket;
+
+ mutex_lock (&_ports_lock);
+
+ loop:
+ if (class->flags & PORT_CLASS_NO_ALLOC)
+ {
+ class->flags |= PORT_CLASS_ALLOC_WAIT;
+ condition_wait (&_ports_block, &_ports_lock);
+ goto loop;
+ }
+ if (bucket->flags & PORT_BUCKET_NO_ALLOC)
+ {
+ bucket->flags |= PORT_BUCKET_ALLOC_WAIT;
+ condition_wait (&_ports_block, &_ports_lock);
+ goto loop;
+ }
+
+ err = ihash_add (bucket->htable, port, pi, &pi->hentry);
+ assert_perror (err);
+ pi->next = class->ports;
+ pi->prevp = &class->ports;
+ class->ports->prevp = &pi->next;
+ class->ports = pi;
+ bucket->count++;
+ class->count++;
+ mutex_unlock (&_ports_lock);
+
+ mach_port_move_member (mach_task_self (), pi->port_right, bucket->portset);
+ return pi;
+}
+
diff --git a/libports/begin-rpc.c b/libports/begin-rpc.c
new file mode 100644
index 00000000..e1541b1d
--- /dev/null
+++ b/libports/begin-rpc.c
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+
+error_t
+ports_begin_rpc (void *portstruct, struct rpc_info *info)
+{
+ struct port_info *pi = portstruct;
+
+ mutex_lock (&_ports_lock);
+
+ start_over:
+
+ /* If our receive right is gone, then abandon the RPC. */
+ if (pi->port_right == MACH_PORT_NULL)
+ {
+ mutex_unlock (&_ports_lock);
+ return EDIED;
+ }
+
+ /* Check to see if RPC's are inhibited */
+ while (_ports_flags & (_PORTS_INHIBITED | _PORTS_INHIBIT_WAIT))
+ {
+ _ports_flags |= _PORTS_BLOCKED;
+ condition_wait (&_ports_block, &_ports_lock);
+ }
+
+ /* Check to see if RPC's are inhibited for this port's bucket */
+ if (pi->bucket->flags & (PORT_BUCKET_INHIBITED | PORT_BUCKET_INHIBIT_WAIT))
+ {
+ pi->bucket->flags |= PORT_BUCKET_BLOCKED;
+ condition_wait (&_ports_block, &_ports_lock);
+ goto start_over;
+ }
+
+ /* Check to see if RPC's are inhibited for this port's class */
+ if (pi->class->flags & (PORT_CLASS_INHIBITED | PORT_CLASS_INHIBIT_WAIT))
+ {
+ pi->class->flags |= PORT_CLASS_BLOCKED;
+ condition_wait (&_ports_block, &_ports_lock);
+ goto start_over;
+ }
+
+ /* Check to see if RPC's are inhibited for this port itself */
+ if (pi->flags & (PORT_INHIBITED | PORT_INHIBIT_WAIT))
+ {
+ pi->flags |= PORT_BLOCKED;
+ condition_wait (&_ports_block, &_ports_lock);
+ goto start_over;
+ }
+
+ /* Record that that an RPC is in progress */
+ info->thread = hurd_thread_self ();
+ info->next = pi->current_rpcs;
+ pi->current_rpcs->prevp = &info->next;
+ info->prevp = &pi->current_rpcs;
+ pi->current_rpcs = info;
+
+ pi->class->rpcs++;
+ pi->bucket->rpcs++;
+ _ports_total_rpcs++;
+ mutex_unlock (&_ports_lock);
+
+ return 0;
+}
+
+
diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c
new file mode 100644
index 00000000..c663cdfe
--- /dev/null
+++ b/libports/complete-deallocate.c
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <assert.h>
+#include <hurd/ihash.h>
+#include <cthreads.h>
+
+void
+_ports_complete_deallocate (struct port_info *pi)
+{
+ assert ((pi->flags & PORT_HAS_SENDRIGHTS) == 0);
+
+ ihash_locp_remove (pi->bucket->htable, pi->hentry);
+ *pi->prevp = pi->next;
+ if (pi->next)
+ pi->next->prevp = pi->prevp;
+
+ pi->bucket->count--;
+ pi->class->count--;
+ mutex_unlock (&_ports_lock);
+
+ mach_port_mod_refs (mach_task_self (), pi->port_right,
+ MACH_PORT_RIGHT_RECEIVE, -1);
+
+ if (pi->class->clean_routine)
+ (*pi->class->clean_routine)(pi);
+
+ free (pi);
+}
+
diff --git a/libports/count-bucket.c b/libports/count-bucket.c
new file mode 100644
index 00000000..d1d771f5
--- /dev/null
+++ b/libports/count-bucket.c
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+
+int
+ports_count_bucket (struct port_bucket *bucket)
+{
+ int ret;
+
+ mutex_lock (&_ports_lock);
+ ret = bucket->count;
+ bucket->flags |= PORT_BUCKET_NO_ALLOC;
+ mutex_unlock (&_ports_lock);
+
+ return ret;
+}
diff --git a/libports/count-class.c b/libports/count-class.c
new file mode 100644
index 00000000..6aa88aa9
--- /dev/null
+++ b/libports/count-class.c
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+
+int
+ports_count_class (struct port_class *class)
+{
+ int ret;
+
+ mutex_lock (&_ports_lock);
+ ret = class->count;
+ class->flags |= PORT_CLASS_NO_ALLOC;
+ mutex_unlock (&_ports_lock);
+ return ret;
+}
+
+
+
diff --git a/libports/create-bucket.c b/libports/create-bucket.c
new file mode 100644
index 00000000..1c3346e4
--- /dev/null
+++ b/libports/create-bucket.c
@@ -0,0 +1,47 @@
+/* Create a port bucket
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <assert.h>
+#include <hurd/ihash.h>
+#include <cthreads.h>
+
+struct port_bucket *
+ports_create_bucket ()
+{
+ struct port_bucket *ret;
+ error_t err;
+
+ ret = malloc (sizeof (struct port_bucket));
+ assert (ret);
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET,
+ &ret->portset);
+ assert_perror (err);
+ err = ihash_create (&ret->htable);
+ assert_perror (err);
+
+ mutex_lock (&_ports_lock);
+ ret->next = _ports_all_buckets;
+ _ports_all_buckets = ret;
+ mutex_unlock (&_ports_lock);
+ return ret;
+}
+
+
diff --git a/libports/create-class.c b/libports/create-class.c
new file mode 100644
index 00000000..fe17f0ba
--- /dev/null
+++ b/libports/create-class.c
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <stdlib.h>
+#include <assert.h>
+
+struct port_class *
+ports_create_class (void (*clean_routine)(void *),
+ void (*dropweak_routine)(void *))
+{
+ struct port_class *cl;
+
+ cl = malloc (sizeof (struct port_class));
+ assert (cl);
+ cl->clean_routine = clean_routine;
+ cl->dropweak_routine = dropweak_routine;
+ cl->flags = 0;
+ cl->rpcs = 0;
+ return cl;
+}
diff --git a/libports/destroy-right.c b/libports/destroy-right.c
new file mode 100644
index 00000000..907e64d7
--- /dev/null
+++ b/libports/destroy-right.c
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <hurd/ihash.h>
+#include <assert.h>
+
+void
+ports_destroy_right (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+ error_t err;
+
+ mutex_lock (&_ports_lock);
+ ihash_locp_remove (pi->bucket->htable, pi->hentry);
+ err = mach_port_mod_refs (mach_task_self (), pi->port_right,
+ MACH_PORT_RIGHT_RECEIVE, -1);
+ assert_perror (err);
+ mutex_unlock (&_ports_lock);
+
+ pi->port_right = MACH_PORT_NULL;
+
+ if (pi->flags & PORT_HAS_SENDRIGHTS)
+ {
+ pi->flags &= ~PORT_HAS_SENDRIGHTS;
+ ports_port_deref (pi);
+ }
+}
+
+
+
diff --git a/libports/enable-bucket.c b/libports/enable-bucket.c
new file mode 100644
index 00000000..ac1af67e
--- /dev/null
+++ b/libports/enable-bucket.c
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+
+void
+ports_enable_bucket (struct port_bucket *bucket)
+{
+ mutex_lock (&_ports_lock);
+ bucket->flags &= ~PORT_BUCKET_NO_ALLOC;
+ if (bucket->flags & PORT_BUCKET_ALLOC_WAIT)
+ {
+ bucket->flags &= PORT_BUCKET_ALLOC_WAIT;
+ condition_broadcast (&_ports_block);
+ }
+ mutex_unlock (&_ports_lock);
+}
diff --git a/libports/enable-class.c b/libports/enable-class.c
new file mode 100644
index 00000000..31d025fa
--- /dev/null
+++ b/libports/enable-class.c
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+
+void
+ports_enable_class (struct port_class *class)
+{
+ mutex_lock (&_ports_lock);
+ class->flags &= ~PORT_CLASS_NO_ALLOC;
+ if (class->flags & PORT_CLASS_ALLOC_WAIT)
+ {
+ class->flags &= ~PORT_CLASS_ALLOC_WAIT;
+ condition_broadcast (&_ports_block);
+ }
+ mutex_unlock (&_ports_lock);
+}
diff --git a/libports/end-rpc.c b/libports/end-rpc.c
new file mode 100644
index 00000000..8eb31180
--- /dev/null
+++ b/libports/end-rpc.c
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+
+void
+ports_end_rpc (void *port, struct rpc_info *info)
+{
+ struct port_info *pi = port;
+
+ mutex_lock (&_ports_lock);
+ *info->prevp = info->next;
+ if (info->next)
+ info->next->prevp = info->prevp;
+ pi->class->rpcs--;
+ _ports_total_rpcs--;
+ pi->bucket->rpcs--;
+
+ if ((!pi->current_rpcs && (pi->flags & PORT_INHIBIT_WAIT))
+ || (!pi->bucket->rpcs && (pi->bucket->flags & PORT_BUCKET_INHIBIT_WAIT))
+ || (!pi->class->rpcs && (pi->class->flags & PORT_CLASS_INHIBIT_WAIT))
+ || (!_ports_total_rpcs && (_ports_flags & _PORTS_INHIBIT_WAIT)))
+ condition_broadcast (&_ports_block);
+
+ mutex_unlock (&_ports_lock);
+}
diff --git a/libports/get-right.c b/libports/get-right.c
new file mode 100644
index 00000000..880c866b
--- /dev/null
+++ b/libports/get-right.c
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <mach/notify.h>
+
+mach_port_t
+ports_get_right (void *port)
+{
+ struct port_info *pi = port;
+ mach_port_t foo;
+
+ mutex_lock (&_ports_lock);
+
+ pi->mscount++;
+ if (pi->flags & PORT_HAS_SENDRIGHTS == 0)
+ {
+ pi->flags |= PORT_HAS_SENDRIGHTS;
+ pi->refcnt++;
+ mach_port_request_notification (mach_task_self (), pi->port_right,
+ MACH_NOTIFY_NO_SENDERS, 1,
+ pi->port_right,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE, &foo);
+ if (foo != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), foo);
+ }
+ mutex_unlock (&_ports_lock);
+ return pi->port_right;
+}
+
+
diff --git a/libports/inhibit-all-rpcs.c b/libports/inhibit-all-rpcs.c
new file mode 100644
index 00000000..953bfc32
--- /dev/null
+++ b/libports/inhibit-all-rpcs.c
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <hurd/ihash.h>
+
+void
+inhibit_all_rpcs ()
+{
+ struct port_bucket *bucket;
+ error_t interruptor (void *portstruct)
+ {
+ struct port_info *pi = portstruct;
+ struct rpc_info *rpc;
+
+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
+ thread_cancel (rpc->thread);
+ return 0;
+ }
+
+ mutex_lock (&_ports_lock);
+
+ for (bucket = _ports_all_buckets; bucket; bucket = bucket->next)
+ ihash_iterate (bucket->htable, interruptor);
+
+ while (_ports_total_rpcs)
+ {
+ _ports_flags |= _PORTS_INHIBIT_WAIT;
+ condition_wait (&_ports_block, &_ports_lock);
+ }
+
+ _ports_flags |= _PORTS_INHIBITED;
+ _ports_flags &= ~_PORTS_INHIBIT_WAIT;
+
+ mutex_unlock (&_ports_lock);
+}
+
+
diff --git a/libports/inhibit-bucket-rpcs.c b/libports/inhibit-bucket-rpcs.c
new file mode 100644
index 00000000..d4daa17d
--- /dev/null
+++ b/libports/inhibit-bucket-rpcs.c
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <hurd/ihash.h>
+
+void
+ports_inhibit_bucket_rpcs (struct port_bucket *bucket)
+{
+ error_t interruptor (void *portstruct)
+ {
+ struct port_info *pi = portstruct;
+ struct rpc_info *rpc;
+
+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
+ thread_cancel (rpc->thread);
+ return 0;
+ }
+
+ mutex_lock (&_ports_lock);
+
+ ihash_iterate (bucket->htable, interruptor);
+
+ while (bucket->rpcs)
+ {
+ bucket->flags |= PORT_BUCKET_INHIBIT_WAIT;
+ condition_wait (&_ports_block, &_ports_lock);
+ }
+
+ bucket->flags |= PORT_BUCKET_INHIBITED;
+ bucket->flags &= ~PORT_CLASS_INHIBIT_WAIT;
+
+ mutex_unlock (&_ports_lock);
+}
diff --git a/libports/inhibit-class-rpcs.c b/libports/inhibit-class-rpcs.c
new file mode 100644
index 00000000..5bc94541
--- /dev/null
+++ b/libports/inhibit-class-rpcs.c
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+
+void
+ports_inhibit_class_rpcs (struct port_class *class)
+{
+ struct port_info *pi;
+ struct rpc_info *rpc;
+
+ mutex_lock (&_ports_lock);
+
+ for (pi = class->ports; pi; pi = pi->next)
+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
+ thread_cancel (rpc->thread);
+
+ while (class->rpcs)
+ {
+ 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
new file mode 100644
index 00000000..60dc187f
--- /dev/null
+++ b/libports/inhibit-port-rpcs.c
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+
+void
+inhibit_port_rpcs (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+ struct rpc_info *rpc;
+
+ mutex_lock (&_ports_lock);
+
+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
+ thread_cancel (rpc->thread);
+
+ while (pi->current_rpcs)
+ {
+ pi->flags |= PORT_INHIBIT_WAIT;
+ condition_wait (&_ports_block, &_ports_lock);
+ }
+
+ pi->flags |= PORT_INHIBITED;
+ pi->flags &= ~PORT_INHIBIT_WAIT;
+
+ mutex_unlock (&_ports_lock);
+}
diff --git a/libports/init.c b/libports/init.c
new file mode 100644
index 00000000..44c8bdd4
--- /dev/null
+++ b/libports/init.c
@@ -0,0 +1,28 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+
+struct mutex _ports_lock = MUTEX_INITIALIZER;
+struct condition _ports_block = CONDITION_INITIALIZER;
+struct port_bucket *_ports_all_buckets = 0;
+int _ports_total_rpcs = 0;
+int _ports_flags = 0;
diff --git a/libports/intern-external-port.c b/libports/intern-external-port.c
new file mode 100644
index 00000000..49139e7d
--- /dev/null
+++ b/libports/intern-external-port.c
@@ -0,0 +1,96 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <assert.h>
+#include <cthreads.h>
+#include <hurd/ihash.h>
+#include <mach/notify.h>
+
+void *ports_intern_external_port (struct port_bucket *bucket,
+ mach_port_t port,
+ size_t size,
+ struct port_class *class)
+{
+ error_t err;
+ mach_port_status_t stat;
+ struct port_info *pi;
+ mach_port_t foo;
+
+ err = mach_port_get_receive_status (mach_task_self (), port, &stat);
+ assert_perror (err);
+
+ if (size < sizeof (struct port_info))
+ size = sizeof (struct port_info);
+
+ pi = malloc (size);
+ assert (pi);
+
+ pi->class = class;
+ pi->refcnt = 1 + !!stat.mps_srights;
+ pi->weakrefcnt = 0;
+ pi->mscount = stat.mps_mscount;
+ pi->flags = stat.mps_srights ? PORT_HAS_SENDRIGHTS : 0;
+ pi->port_right = port;
+ pi->current_rpcs = 0;
+ pi->bucket = bucket;
+
+ mutex_lock (&_ports_lock);
+
+ loop:
+ if (class->flags & PORT_CLASS_NO_ALLOC)
+ {
+ class->flags |= PORT_CLASS_ALLOC_WAIT;
+ condition_wait (&_ports_block, &_ports_lock);
+ goto loop;
+ }
+ if (bucket->flags & PORT_BUCKET_NO_ALLOC)
+ {
+ bucket->flags |= PORT_BUCKET_ALLOC_WAIT;
+ condition_wait (&_ports_block, &_ports_lock);
+ goto loop;
+ }
+
+ err = ihash_add (bucket->htable, port, pi, &pi->hentry);
+ assert_perror (err);
+ pi->next = class->ports;
+ pi->prevp = &class->ports;
+ class->ports->prevp = &pi->next;
+ class->ports = pi;
+ bucket->count++;
+ class->count++;
+ mutex_unlock (&_ports_lock);
+
+ mach_port_move_member (mach_task_self (), port, bucket->portset);
+
+ if (stat.mps_srights)
+ {
+ err = mach_port_request_notification (mach_task_self (), port,
+ MACH_NOTIFY_NO_SENDERS,
+ stat.mps_mscount,
+ port, MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &foo);
+ assert_perror (err);
+ if (foo != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), foo);
+ }
+
+ return pi;
+}
diff --git a/libports/interrupt-rpcs.c b/libports/interrupt-rpcs.c
new file mode 100644
index 00000000..930ed201
--- /dev/null
+++ b/libports/interrupt-rpcs.c
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+
+void
+ports_interrupt_rpc (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+ struct rpc_info *rpc;
+
+ mutex_lock (&_ports_lock);
+
+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
+ thread_cancel (rpc->thread);
+
+ mutex_unlock (&_ports_lock);
+}
+
+
diff --git a/libports/lookup-port.c b/libports/lookup-port.c
new file mode 100644
index 00000000..3db912c6
--- /dev/null
+++ b/libports/lookup-port.c
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <hurd/ihash.h>
+
+void *
+ports_lookup_port (struct port_bucket *bucket,
+ mach_port_t port,
+ struct port_class *class)
+{
+ struct port_info *pi = 0;
+
+ mutex_lock (&_ports_lock);
+
+ if (bucket)
+ pi = ihash_find (bucket->htable, port);
+ else
+ for (bucket = _ports_all_buckets; bucket; bucket = bucket->next)
+ if (pi = ihash_find (bucket->htable, port))
+ break;
+
+ if (pi && class && pi->class != class)
+ pi = 0;
+
+ if (pi)
+ pi->refcnt++;
+
+ mutex_lock (&_ports_lock);
+
+ return pi;
+}
+
+
diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c
new file mode 100644
index 00000000..767d9ee7
--- /dev/null
+++ b/libports/manage-multithread.c
@@ -0,0 +1,123 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <spin-lock.h>
+#include <assert.h>
+#include <cthreads.h>
+
+void
+ports_manage_port_operations_multithread (struct port_bucket *bucket,
+ ports_demuxer_type demuxer,
+ int thread_timeout,
+ int global_timeout,
+ int wire_cthreads,
+ mach_port_t wire_threads)
+{
+ error_t err;
+ int nreqthreads = 0;
+ int totalthreads = 0;
+ spin_lock_t lock = SPIN_LOCK_INITIALIZER;
+
+ auto void thread_function (int);
+
+ int
+ internal_demuxer (mach_msg_header_t *inp,
+ mach_msg_header_t *outp)
+ {
+ int spawn = 0;
+ int status;
+ struct port_info *pi;
+ struct rpc_info link;
+
+ spin_lock (&lock);
+ assert (nreqthreads);
+ nreqthreads--;
+ if (nreqthreads == 0)
+ spawn = 1;
+ spin_unlock (&lock);
+
+ if (spawn)
+ cthread_detach (cthread_fork ((cthread_fn_t) thread_function, 0));
+
+ pi = ports_lookup_port (bucket, inp->msgh_local_port, 0);
+ ports_begin_rpc (pi, &link);
+ status = demuxer (inp, outp);
+ ports_end_rpc (pi, &link);
+ ports_port_deref (pi);
+
+ spin_lock (&lock);
+ nreqthreads++;
+ spin_unlock (&lock);
+
+ return status;
+ }
+
+ void
+ thread_function (int master)
+ {
+ int timeout;
+
+ if (wire_threads)
+ thread_wire (wire_threads, hurd_thread_self (), 1);
+ if (wire_cthreads)
+ cthread_wire ();
+
+ spin_lock (&lock);
+ totalthreads++;
+ nreqthreads++;
+ if (master)
+ timeout = global_timeout;
+ else
+ timeout = thread_timeout;
+ spin_unlock (&lock);
+
+ startover:
+
+ do
+ err = mach_msg_server_timeout (internal_demuxer, 0, bucket->portset,
+ timeout ? MACH_RCV_TIMEOUT : 0,
+ timeout);
+ while (err != MACH_RCV_TIMED_OUT);
+
+ if (master)
+ {
+ spin_lock (&lock);
+ if (totalthreads != 1)
+ goto startover;
+ return;
+ }
+ else
+ {
+ spin_lock (&lock);
+ nreqthreads--;
+ totalthreads--;
+ spin_unlock (&lock);
+ cthread_exit (0);
+ }
+ }
+
+ thread_function (1);
+}
+
+
+
+
+
diff --git a/libports/manage-one-thread.c b/libports/manage-one-thread.c
new file mode 100644
index 00000000..41cf4b70
--- /dev/null
+++ b/libports/manage-one-thread.c
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+
+void
+ports_manage_port_operations_one_thread (struct port_bucket *bucket,
+ ports_demuxer_type demuxer,
+ int timeout)
+{
+ error_t err;
+
+ int
+ internal_demuxer (mach_msg_header_t *inp,
+ mach_msg_header_t *outp)
+ {
+ struct port_info *pi;
+ struct rpc_info link;
+ int status;
+ error_t err;
+
+ pi = ports_lookup_port (bucket, inp->msgh_local_port, 0);
+ err = ports_begin_rpc (pi, &link);
+ if (err)
+ {
+ mach_port_deallocate (mach_task_self (), inp->msgh_remote_port);
+ status = 0;
+ }
+ else
+ {
+ status = demuxer (inp, outp);
+ ports_end_rpc (pi, &link);
+ }
+
+ ports_port_deref (pi);
+
+ return status;
+ }
+
+ do
+ err = mach_msg_server_timeout (internal_demuxer, 0, bucket->portset,
+ timeout ? MACH_RCV_TIMEOUT : 0, timeout);
+ while (err != MACH_RCV_TIMED_OUT);
+}
+
+
diff --git a/libports/no-senders.c b/libports/no-senders.c
new file mode 100644
index 00000000..09a32dfc
--- /dev/null
+++ b/libports/no-senders.c
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <mach/notify.h>
+
+void
+ports_no_senders (void *portstruct,
+ mach_port_mscount_t mscount)
+{
+ struct port_info *pi = portstruct;
+ int dealloc;
+ mach_port_t old;
+
+ mutex_lock (&_ports_lock);
+ if ((pi->flags & PORT_HAS_SENDRIGHTS) == 0)
+ {
+ mutex_unlock (&_ports_lock);
+ return;
+ }
+ if (mscount >= pi->mscount)
+ {
+ dealloc = 1;
+ pi->flags &= ~PORT_HAS_SENDRIGHTS;
+ }
+ else
+ {
+ /* Request a new notification. The sync value is because
+ we might have accounted for a new sender but not actually
+ made the send right yet. */
+ mach_port_request_notification (mach_task_self (), pi->port_right,
+ MACH_NOTIFY_NO_SENDERS, pi->mscount,
+ pi->port_right,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE, &old);
+ if (old)
+ mach_port_deallocate (mach_task_self (), old);
+ dealloc = 0;
+ }
+ mutex_unlock (&_ports_lock);
+
+ if (dealloc)
+ ports_port_deref (pi);
+}
diff --git a/libports/port-deref-weak.c b/libports/port-deref-weak.c
new file mode 100644
index 00000000..2bef3338
--- /dev/null
+++ b/libports/port-deref-weak.c
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <assert.h>
+
+void
+ports_port_deref_weak (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+
+ mutex_lock (&_ports_lock);
+ assert (pi->weakrefcnt);
+ pi->weakrefcnt--;
+ if (pi->refcnt == 0 && pi->weakrefcnt == 0)
+ _ports_complete_deallocate (pi);
+ else
+ mutex_unlock (&_ports_lock);
+}
+
diff --git a/libports/port-deref.c b/libports/port-deref.c
new file mode 100644
index 00000000..a1238315
--- /dev/null
+++ b/libports/port-deref.c
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <assert.h>
+
+void
+ports_port_deref (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+ int trieddroppingweakrefs = 0;
+
+ retry:
+
+ mutex_lock (&_ports_lock);
+
+ if (pi->refcnt == 1 && pi->weakrefcnt && !trieddroppingweakrefs)
+ {
+ mutex_unlock (&_ports_lock);
+ if (pi->class->dropweak_routine)
+ (*pi->class->dropweak_routine) (pi);
+ trieddroppingweakrefs = 1;
+ goto retry;
+ }
+
+ assert (pi->refcnt);
+
+ pi->refcnt--;
+ if (pi->refcnt == 0 && pi->weakrefcnt == 0)
+ _ports_complete_deallocate (pi);
+ else
+ mutex_unlock (&_ports_lock);
+}
+
+
diff --git a/libports/port-ref-weak.c b/libports/port-ref-weak.c
new file mode 100644
index 00000000..6ebd5608
--- /dev/null
+++ b/libports/port-ref-weak.c
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <assert.h>
+
+void
+ports_port_ref_weak (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+
+ mutex_lock (&_ports_lock);
+ assert (pi->refcnt || pi->weakrefcnt);
+ pi->weakrefcnt++;
+ mutex_unlock (&_ports_lock);
+}
diff --git a/libports/port-ref.c b/libports/port-ref.c
new file mode 100644
index 00000000..7fd15272
--- /dev/null
+++ b/libports/port-ref.c
@@ -0,0 +1,36 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <assert.h>
+
+void
+ports_port_ref (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+
+ mutex_lock (&_ports_lock);
+ assert (pi->refcnt || pi->weakrefcnt);
+ pi->refcnt++;
+ mutex_unlock (&_ports_lock);
+}
+
+
diff --git a/libports/reallocate-from-external.c b/libports/reallocate-from-external.c
new file mode 100644
index 00000000..74e6d76c
--- /dev/null
+++ b/libports/reallocate-from-external.c
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <assert.h>
+#include <cthreads.h>
+#include <hurd/ihash.h>
+#include <mach/notify.h>
+
+void
+ports_reallocate_from_external (void *portstruct, mach_port_t receive)
+{
+ struct port_info *pi = portstruct;
+ mach_port_status_t stat;
+ int dropref = 0;
+ mach_port_t foo;
+ error_t err;
+
+ err = mach_port_get_receive_status (mach_task_self (), receive, &stat);
+ assert_perror (err);
+
+ mutex_lock (&_ports_lock);
+
+ err = mach_port_mod_refs (mach_task_self (), pi->port_right,
+ MACH_PORT_RIGHT_RECEIVE, -1);
+ assert_perror (err);
+
+ ihash_locp_remove (pi->bucket->htable, pi->hentry);
+
+ if ((pi->flags & PORT_HAS_SENDRIGHTS) && !stat.mps_srights)
+ {
+ dropref = 1;
+ pi->flags &= ~PORT_HAS_SENDRIGHTS;
+ }
+ else if ((pi->flags & PORT_HAS_SENDRIGHTS == 0) && stat.mps_srights)
+ {
+ pi->flags |= PORT_HAS_SENDRIGHTS;
+ pi->refcnt++;
+ }
+
+ pi->port_right = receive;
+ pi->mscount = stat.mps_mscount;
+
+ ihash_add (pi->bucket->htable, receive, pi, &pi->hentry);
+ mutex_unlock (&_ports_lock);
+
+ mach_port_move_member (mach_task_self (), receive, pi->bucket->portset);
+
+ if (stat.mps_srights)
+ {
+ err = mach_port_request_notification (mach_task_self (), receive,
+ MACH_NOTIFY_NO_SENDERS,
+ stat.mps_mscount, receive,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &foo);
+ assert_perror (err);
+ if (foo != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), foo);
+ }
+
+ if (dropref)
+ ports_port_deref (pi);
+}
diff --git a/libports/reallocate-port.c b/libports/reallocate-port.c
new file mode 100644
index 00000000..b2785292
--- /dev/null
+++ b/libports/reallocate-port.c
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <hurd/ihash.h>
+#include <assert.h>
+#include <cthreads.h>
+
+void
+ports_reallocate_port (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+ error_t err;
+ int dropref = 0;
+
+ mutex_lock (&_ports_lock);
+ err = mach_port_mod_refs (mach_task_self (), pi->port_right,
+ MACH_PORT_RIGHT_RECEIVE, -1);
+ assert_perror (err);
+
+ ihash_locp_remove (pi->bucket->htable, pi->hentry);
+
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
+ &pi->port_right);
+ assert_perror (err);
+ if (pi->flags & PORT_HAS_SENDRIGHTS)
+ {
+ pi->flags &= ~PORT_HAS_SENDRIGHTS;
+ dropref = 1;
+ }
+ pi->mscount = 0;
+ ihash_add (pi->bucket->htable, pi->port_right, pi, &pi->hentry);
+ mutex_unlock (&_ports_lock);
+
+ mach_port_move_member (mach_task_self (), pi->port_right,
+ pi->bucket->portset);
+
+ if (dropref)
+ ports_port_deref (pi);
+}
+
+
+
+
+
diff --git a/libports/resume-all-rpcs.c b/libports/resume-all-rpcs.c
new file mode 100644
index 00000000..fa978c1e
--- /dev/null
+++ b/libports/resume-all-rpcs.c
@@ -0,0 +1,39 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <assert.h>
+
+void
+ports_resume_all_rpcs ()
+{
+ mutex_lock (&_ports_lock);
+ assert (_ports_flags & _PORTS_INHIBITED);
+ _ports_flags &= ~_PORTS_INHIBITED;
+ if (_ports_flags | _PORTS_BLOCKED)
+ {
+ _ports_flags &= ~_PORTS_BLOCKED;
+ condition_broadcast (&_ports_block);
+ }
+ mutex_unlock (&_ports_lock);
+}
+
+
diff --git a/libports/resume-bucket-rpcs.c b/libports/resume-bucket-rpcs.c
new file mode 100644
index 00000000..9d968874
--- /dev/null
+++ b/libports/resume-bucket-rpcs.c
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <assert.h>
+
+void
+ports_resume_bucket_rpcs (struct port_bucket *bucket)
+{
+ mutex_lock (&_ports_lock);
+ assert (bucket->flags & PORT_BUCKET_INHIBITED);
+ bucket->flags &= ~PORT_BUCKET_INHIBITED;
+ if (bucket->flags | PORT_BUCKET_BLOCKED)
+ {
+ bucket->flags &= ~PORT_BUCKET_BLOCKED;
+ condition_broadcast (&_ports_block);
+ }
+ mutex_unlock (&_ports_lock);
+}
diff --git a/libports/resume-class-rpcs.c b/libports/resume-class-rpcs.c
new file mode 100644
index 00000000..f0516bd5
--- /dev/null
+++ b/libports/resume-class-rpcs.c
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <assert.h>
+
+void
+ports_resume_class_rpcs (struct port_class *class)
+{
+ mutex_lock (&_ports_lock);
+ assert (class->flags & PORT_CLASS_INHIBITED);
+ class->flags &= ~PORT_CLASS_INHIBITED;
+ if (class->flags | PORT_CLASS_BLOCKED)
+ {
+ class->flags &= ~PORT_BLOCKED;
+ condition_broadcast (&_ports_block);
+ }
+ mutex_unlock (&_ports_lock);
+}
+
diff --git a/libports/resume-port-rpcs.c b/libports/resume-port-rpcs.c
new file mode 100644
index 00000000..563c9adc
--- /dev/null
+++ b/libports/resume-port-rpcs.c
@@ -0,0 +1,43 @@
+/*
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ports.h"
+#include <cthreads.h>
+#include <assert.h>
+
+void
+ports_resume_port_rpcs (void *portstruct)
+{
+ struct port_info *pi = portstruct;
+
+ mutex_lock (&_ports_lock);
+
+ assert (pi->flags & PORT_INHIBITED);
+ pi->flags &= ~PORT_INHIBITED;
+ if (pi->flags | PORT_BLOCKED)
+ {
+ pi->flags &= ~PORT_BLOCKED;
+ condition_broadcast (&_ports_block);
+ }
+ mutex_unlock (&_ports_lock);
+}
+
+
+