diff options
author | Michael I. Bushnell <mib@gnu.org> | 1995-06-20 16:31:54 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1995-06-20 16:31:54 +0000 |
commit | a6f82b9d63d88072693024404a981b19a5c1e7eb (patch) | |
tree | b9ecbaa316e21221f18bf3e04fbe39ee6c63dda4 | |
parent | fba5e72c73d8f31cc5324bbed379d5bfe16061fe (diff) |
Initial revision
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); +} + + + |