diff options
Diffstat (limited to 'libports')
37 files changed, 415 insertions, 677 deletions
diff --git a/libports/ChangeLog b/libports/ChangeLog deleted file mode 100644 index 2a50f7ce..00000000 --- a/libports/ChangeLog +++ /dev/null @@ -1,438 +0,0 @@ -Thu Jul 18 22:59:14 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (SRCS): Add create-port-noinstall.c and create-internal.c. - * create-port-noinstall.c: New file. - * create-port.c (ports_create_port): Guts deleted; call new work - function. - * create-internal.c: New file; all the guts from create-port.c. - -Wed Jul 3 14:13:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * get-right.c (ports_get_right): Supply correct sync value in - notification request. - -Mon May 6 16:33:55 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * ports.h (ports_allocate_port, ports_intern_external_port): - Delete obsolete declarations. - * allocate-port.c, intern-external-port.c: Delete files. - * Makefile (SRCS): Delete `intern-external-port.c' and - `allocate-port.c'. - -Sun Apr 28 15:22:58 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> - - * allocate-port.c: Add obsolescence link warning. - * intern-external-port.c: Add obsolescence link warning. - -Fri Mar 29 15:21:31 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * end-rpc.c (ports_end_rpc): Acquire _PORTS_LOCK before calling - _ports_remove_notified_rpc. - -Fri Mar 29 09:04:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * reallocate-from-external.c (ports_reallocate_from_external): - Require port to have a current port right. - * reallocate-port.c (ports_reallocate_port): Likewise. - - * complete-deallocate.c (_ports_complete_deallocate): Only drop - port right if it isn't already null. - - * transfer-right.c: New file. - * Makefile (SRCS): Add transfer-right.c. - * ports.h (ports_claim_right): Doc fix. - (ports_transfer_right): New function. - -Thu Mar 28 10:47:58 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * claim-right.c (ports_claim_right): Take right out of port - bucket. - - * manage-multithread.c (ports_manage_port_operations_multithread): - Fill in meaningful statuses and errors rather than just zero. - * manage-one-thread.c (ports_manage_port_operations_one_thread): - Likewise. - - * begin-rpc.c (ports_begin_rpc): Return EOPNOTSUPP, not EDIED, if - receive right is gone. - - * manage-one-thread.c (ports_manage_port_operations_one_thread): - Fill in default reply before doing work; we might return 0 and - mach_msg_server expects us to fill in a reply decently no matter - what. - (ports_manage_port_operations_multithread): Likewise. - - * claim-right.c (ports_claim_right): Hold lock until sendright - frobbing is finished. - -Wed Mar 20 13:32:13 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * destroy-right.c (ports_destroy_right): Don't do anything if port - has already been destroyed. - - * ports.h (ports_claim_right): New declaration. - * claim-right.c: New file. - * Makefile (SRCS): Add `claim-right.c'. - -Tue Mar 5 17:28:54 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * get-right.c (ports_get_right): Check mach_port_request_notification - for error returns, against all odds. - -Mon Feb 26 17:10:38 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * interrupt-on-notify.c (ports_interrupt_rpc_on_notification): - Only set _PORTS_NOTIFICATIONS->prevp if _PORTS_NOTIFICATIONS != 0. - Likewise for PN->prev_req_p. - -Fri Jan 26 00:45:58 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inhibit-class-rpcs.c (ports_inhibit_class_rpcs): Whoops, we - still have the lock when hurd_condition_wait gets cancelled. - * import-port.c (ports_import_port): Likewise. - * create-port.c (ports_create_port): Likewise. - * inhibit-bucket-rpcs.c (ports_inhibit_bucket_rpcs): Likewise. - * inhibit-all-rpcs.c (ports_inhibit_all_rpcs): Likewise. - * inhibit-port-rpcs.c (ports_inhibit_port_rpcs): Likewise. - - * import-port.c (ports_import_port): Don't lose a send right on - PORT when we return an error. - * create-port.c (ports_create_port): Delete the receive right, not - the send right when we return an error. - -Thu Jan 25 12:10:48 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * manage-multithread.c (ports_manage_port_operations_multithread): - Pass INP->msgh_id, not INP to ports_begin_rpc. - * manage-one-thread.c (ports_manage_port_operations_one_thread): Ditto. - -Wed Jan 24 14:02:30 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * inhibit-all-rpcs.c (ports_inhibit_all_rpcs): Be interruptable; - return EINTR if interrupted, or EBUSY if already inhibited. - * inhibit-class-rpcs.c (ports_inhibit_class_rpcs): Likewise. - * inhibit-port-rpcs.c (ports_inhibit_port_rpcs): Likewise. - * inhibit-bucket-rpcs.c (ports_inhibit_bucket_rpcs): Likewise. - * begin-rpc.c (ports_begin_rpc): Be interruptable. - * create-port.c (ports_create_port): New function. - * import-port.c (ports_import_port): New function. - * allocate-port.c (ports_allocate_port): Call ports_create_port. - * intern-external-port.c (ports_intern_external_port): Call - ports_import_port. - * ports.h (ports_create_port, ports_import_ports): New declarations. - (PORTS_INHIBITED, PORTS_BLOCKED, PORTS_INHIBIT_WAIT, PORTS_NO_ALLOC, - PORTS_ALLOC_WAIT): New macros (global values for common flags). - (PORT_BLOCKED, PORT_INHIBITED, PORT_INHIBIT_WAIT, - PORT_BUCKET_INHIBITED, PORT_BUCKET_BLOCKED, PORT_BUCKET_INHIBIT_WAIT, - PORT_BUCKET_NO_ALLOC, PORT_BUCKET_ALLOC_WAIT, PORT_CLASS_INHIBITED, - PORT_CLASS_BLOCKED, PORT_CLASS_INHIBIT_WAIT, PORT_CLASS_NO_ALLOC, - PORT_CLASS_ALLOC_WAIT, _PORTS_INHIBITED, _PORTS_BLOCKED, - _PORTS_INHIBIT_WAIT): Redefine using global flag values. - (ports_inhibit_port_rpcs, ports_inhibit_all_rpcs, - ports_inhibit_class_rpcs, ports_inhibit_bucket_rpcs): Return error_t. - (ports_interupt_rpcs): Renamed from port_interrupt_rpc. - - * begin-rpc.c (ports_begin_rpc): Take new MSG_ID arg, and use it to - see if the particular rpc shouldn't be inhibitable. - * manage-multithread.c (ports_manage_port_operations_multithread): - Pass INP to ports_begin_rpc, and only call DEMUXER if it returns 0. - * manage-one-thread.c (ports_manage_port_operations_one_thread): Ditto. - * ports.h (ports_begin_rpc): Add MSG_ID arg. - (struct port_class): Add uninhibitable_rpcs field. - (struct ports_msg_id_range): New structure. - (ports_default_uninhibitable_rpcs): New declaration. - * create-class.c (ports_create_class): Initialize the - uninhibitable_rpcs field. - * default-uninhibitable-rpcs.c (interrupt_operation_ids, - ports_default_uninhibitable_rpcs): New variables. - * Makefile (SRCS): Add default-uninhibitable-rpcs.c. - - * interrupt-rpcs.c (ports_interrupt_rpcs): Renamed from - ports_interrupt_rpc. - * Makefile (SRCS): Rename interrupt-rpc.c to interrupt-rpcs.c. - * interrupt-operation.c (ports_S_interrupt_operation): Use - ports_interrupt_rpcs instead of ports_interrupt_rpc. - * no-senders.c (ports_no_senders): Likewise. - - * manage-multithread.c (ports_manage_port_operations_multithread): - Fix spelling of cancel_threshold (was cancel_threshhold). - * interrupt-operation.c (ports_S_interrupt_operation): Likewise. - * ports.h (struct port_info): Likewise. - * reallocate-from-external.c (ports_reallocate_from_external): Ditto. - * reallocate-port.c (ports_reallocate_port): Likewise. - -Wed Jan 17 13:08:49 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * no-senders.c (ports_no_senders): Interrupt RPCs on PI too. Only - do the ports_interrupt_notified_rpcs() if we're actually losing a ref. - -Fri Jan 5 16:40:34 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * interrupt-on-notify.c (ports_interrupt_rpc_on_notification): - If PORT is dead or bogus, interrupt RPC immediately, and don't add - a new request. - -Thu Dec 28 14:27:41 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * interrupt-on-notify.c (ports_interrupt_rpc_on_notification): If - NEW_REQ is not needed, put it on the free list, don't call free on it. - -Thu Dec 28 11:04:06 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * ports.h (ports_interrupt_self_on_port_death): New macro. - - * interrupt-notified-rpcs.c (ports_interrupt_notified_rpcs): Only - bother to lock _PORTS_LOCK if there are notifications. - -Wed Dec 27 16:27:47 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * ports.h (struct rpc_info): Get rid of next_notified/prev_notified_p. - (struct rpc_notify): Get rid of port, what, next fields, and add - rpc, notify, next, pending, next_req, and prev_req_p fields. - (struct ports_notify): New structure. - (_ports_notified_rpcs): Declaration removed. - (_ports_notifications): New declaration. - (_ports_free_ports_notifies): New declaration. - Include <mach/notify.h>. - * interrupt-on-notify.c (ports_interrupt_rpc_on_notification): - Mostly rewrite to use new scheme. - * interrupt-notified-rpcs (_ports_notified_rpcs): Variable removed. - (_ports_notifications, _ports_free_ports_notifications): New variables. - (ports_interrupt_notified_rpcs): Rewrite to use new scheme. - (_ports_remove_notified_rpc): Ditto. - (cancel_notification): Function removed. - (remove_req): New function. - -Tue Dec 26 14:39:51 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * interrupt-notified-rpcs.c (_ports_notified_rpcs, - _ports_free_rpc_notifies): New variables. - (ports_interrupt_notified_rpcs, cancel_notification, - _ports_remove_notified_rpc): New functions. - * interrupt-on-notify.c (ports_interrupt_rpc_on_notification, - ports_interrupt_self_on_notification): New functions, new file. - * ports.h (struct rpc_notify): New structure. - (struct rpc_info): Add rpc_notifies, rpc_next_notified, and - prev_notified_p fields. - (_ports_notified_rpcs, _ports_free_rpc_notifies, - _ports_remove_notified_rpc, ports_interrupt_rpc_on_notification, - ports_interrupt_notified_rpcs, ports_interrupt_self_on_notification): - New declarations. - * begin-rpc.c (ports_begin_rpc): Initialize the notifies field. - * end-rpc.c (ports_end_rpc): Get rid of any rpc notifications. - * no-senders.c (ports_no_senders): Interrupt any rpcs requesting such. - * dead-name.c (ports_dead_name): New function. - * notify-dead-name.c (ports_do_mach_notify_dead_name): Call - ports_dead_name(). - * Makefile (SRCS): Add interrupt-on-notify.c, - interrupt-notified-rpcs.c, and dead-name.c. - -Tue Nov 21 22:04:28 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * manage-multithread.c: Don't wire timeouts to zero. - -Tue Nov 21 09:42:00 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * ports.h (ports_do_mach_notify_dead_name): Declare `extern - kern_return_t'. - (ports_do_mach_notify_msg_accepted): Likewise. - (ports_do_mach_notify_no_senders): Likewise. - (ports_do_mach_notify_port_deleted): Likewise. - (ports_do_mach_notify_port_destroyed): Likewise. - (ports_do_mach_notify_send_once): Likewise. - * notify-send-once.c: Include "notify_S.h". - * notify-port-deleted.c: Likewise. - * notify-msg-accepted.c: Likewise. - * notify-port-destroyed.c: Likewise. - * notify-no-senders.c: Likewise. - * notify-dead-name.c: Likewise. - - * ports.h (struct port_info): New member `cancel_threshhold'. - (ports_S_interrupt_operation): Include seqno arg; declare extern - kern_return_t. - * interrupt-operation.c: Include "interrupt_S.h". - (ports_S_interrupt_operation): Set PI->cancel_threshhold if the - incoming seqno is greater than the current threshhold. - * manage-multithread.c - (ports_manage_port_operations_multithread/internal_demuxer): If - the incoming RPC has already been cancelled, then call - hurd_thread_cancel before the user's demuxer. - * manage-one-thread.c (ports_manage_port_operations_one_thread): - Doc fix. - * intern-external-port.c (ports_intern_external_port): Initialize - PI->cancel_threshhold. - * allocate-port.c (ports_allocate_port): Likewise. - * reallocate-from-external.c (ports_reallocate_from_external): - Clear PI->cancel_threshhold. - * reallocate-port.c (ports_reallocate_port): Likewise. - -Sat Nov 18 08:50:13 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * inhibit-all-rpcs.c: If calling thread is serving an RPC, don't - block waiting for that RPC to finish. - * inhibit-class-rpcs.c: Likewise. - * inhibit-bucket-rpcs.c: Likewise. - * inhibit-port-rpcs.c: Likewise. - - * inhibit-all-rpcs.c (ports_inhibit_all_rpcs): Renamed from - inhibit_all_rpcs. - -Tue Oct 24 13:32:39 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * manage-multithread.c - (ports_manage_port_operations_multithread/internal_demuxer): Don't - attempt RPC if we can't get a valid port struct. - * manage-one-thread.c - (ports_manage_port_operations_one_thread/internal_demuxer): Likewise. - -Mon Oct 9 14:57:48 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile: Specify shared library dependencies. - -Fri Sep 22 10:19:17 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * ports.h: Include hurd.h. - -Fri Sep 8 14:44:03 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu> - - * end-rpc.c (ports_end_rpc): Call hurd_check_cancel. - -Wed Sep 6 11:20:20 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * ports.h (ports_interrupt_server, ports_S_interrupt_operation): - New declarations. - * Makefile (OBJS): Add interruptServer.o. - (SRCS): Add interrupt-operation.c. - * interrupt-operation.c: New file. - - * ports.h (ports_notify_server, ports_do_mach_notify_*): New decls. - * Makefile (MIGCOMSFLAGS): New variable. - (OBJS): Added notifyServer.o. - (SRCS): Added notify-dead-name.c, notify-no-senders.c, - notify-port-destroyed.c, notify-msg-accepted.c, - notify-port-deleted.c, and notify-send-once.c. - * notify-dead-name.c: New file. - * notify-no-senders.c: New file. - * notify-port-destroyed.c: New file. - * notify-msg-accepted.c: New file. - * notify-port-deleted.c: New file. - * notify-send-once.c: New file. - -Wed Aug 30 16:00:36 1995 Miles Bader <miles@geech.gnu.ai.mit.edu> - - * inhibit-port-rpcs.c (inhibit_port_rpcs): Renamed to - `ports_inhibit_port_rpcs'. - -Tue Aug 29 15:59:49 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu> - - * manage-multithread.c (ports_manage_port_operations_multithread): - Hammer WIRE_CTHREADS on for now. - -Thu Aug 24 10:25:52 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * inhibit-port-rpcs.c (inhibit_port_rpcs): thread_cancel -> - hurd_thread_cancel. Include <hurd.h>. - * inhibit-class-rpcs.c (ports_inhibit_class_rpcs): Ditto. - * inhibit-bucket-rpcs.c (ports_inhibit_bucket_rpcs): Ditto. - * interrupt-rpc.c (ports_interrupt_rpc): Ditto. - * inhibit-all-rpcs.c (inhibit_all_rpcs): Ditto. - - * Makefile (OBJS): Use :.c=.o notation. - -Wed Aug 23 15:03:11 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile (REMHDRS): Removed. - Order changed a bit. - -Fri Jul 21 11:45:22 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * get-right.c (ports_get_right): If the right is null (because we - are closing down), then just return null. (This helps in a race - in ufs/ex2fs). - - * complete-deallocate.c (_ports_complete_deallocate): Clear - PI->port_right; and do it before releasing _ports_lock. - - * manage-multithread.c (ports_manage_port_operations_multithread): - For now, wire GLOBAL_TIMEOUT and THREAD_TIMEOUT to zero. - -Tue Jul 18 14:29:49 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * manage-multithread.c (ports_manage_port_operations_multithread) - [thread_function]: Return int. Don't cthread_exit child threads; - just let them return normally. - -Wed Jul 12 13:32:22 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * resume-class-rpcs.c (ports_resume_class_rpcs): Clear blocked - flag using correct name. - - * manage-multithread.c (ports_manage_port_operations_multithread) - [internal_demuxer]: Increment NREQTHREADS and TOTALTHREADS - *before* forking newthread. - [thread_function]: Don't increment NREQTHREADS and TOTALTHREADS here. - Initialize NREQTHREADS and TOTALTHREADS in main body of function. - -Sat Jul 8 15:10:50 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * allocate-port.c (ports_allocate_port): Properly add PI to - CLASS's port list when the list is empty (why did this work before?). - * intern-external-port.c (ports_intern_external_port): Ditto. - * begin-rpc.c (ports_begin_rpc): Ditto adding INFO to PI's - current_rpcs list. - * create-class.c (ports_create_class): Initialize the PORTS and - COUNT fields. - -Thu Jul 6 15:36:57 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile: Removed dependencies that are now automatically - generated. - -Tue Jun 27 15:28:54 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile (SRCS): Add it *back*. - * stubs.c: New file. - -Mon Jun 26 16:51:42 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * ports.h: Fix spelling error. - - * manage-multithread.c (ports_manage_port_operations_multithread): - Declare NREQTHREADS asd TOTALTHREADS volatile. - - * manage-multithread.c - (ports_manage_port_operations_multithread/thread_function): Don't - hold lock while setting TIMEOUT. - When master goes back to wait for messages, it should unlock LOCK. - Declare ERR inside THREAD_FUNCTION so it doesn't get shared by - multiple threads. - -Thu Jun 22 11:28:56 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * get-right.c (ports_get_right): Parenthesize flag test correctly. - * reallocate-from-external.c (ports_reallocate_from_external): - Likewise. - - * enable-bucket.c (ports_enable_bucket): Clean flag correctly. - - * lookup-port.c (ports_lookup_port): UNlock port lock at exit of - function. - - * bucket-iterate.c: Include <hurd/ihash.h> and <cthreads.h>. - (ports_bucket_iterate): Fix decl of NXT. - -Wed Jun 21 14:25:04 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile (SRCS): Added bucket-iterate.c. - * bucket-iterate.c: New file. - * ports.h (port_bucket_iterate): New decl. - -Tue Jun 20 12:35:44 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * enable-bucket.c: Include <cthreads.h>. - * enable-class.c: Likewise. - * count-bucket.c: Likewise. - - * libports/lookup-port.c (ports_lookup_port): Remove assignment - from if test. - diff --git a/libports/Makefile b/libports/Makefile index 50ccd0c9..50b5ed9e 100644 --- a/libports/Makefile +++ b/libports/Makefile @@ -1,5 +1,5 @@ -# -# Copyright (C) 1995, 1996 Free Software Foundation, Inc. +# +# Copyright (C) 1995,96,97,99,2000 Free Software Foundation, Inc. # Written by Michael I. Bushnell. # # This file is part of the GNU Hurd. @@ -29,22 +29,22 @@ SRCS = create-bucket.c create-class.c \ inhibit-port-rpcs.c inhibit-class-rpcs.c inhibit-bucket-rpcs.c \ inhibit-all-rpcs.c resume-port-rpcs.c resume-class-rpcs.c \ resume-bucket-rpcs.c resume-all-rpcs.c interrupt-rpcs.c \ - init.c complete-deallocate.c get-right.c count-class.c count-bucket.c \ - enable-class.c enable-bucket.c bucket-iterate.c stubs.c \ + init.c complete-deallocate.c get-right.c get-send-right.c \ + count-class.c count-bucket.c \ + enable-class.c enable-bucket.c bucket-iterate.c class-iterate.c stubs.c \ notify-dead-name.c notify-no-senders.c notify-port-destroyed.c \ notify-msg-accepted.c notify-port-deleted.c notify-send-once.c \ interrupt-operation.c interrupt-on-notify.c interrupt-notified-rpcs.c \ dead-name.c create-port.c import-port.c default-uninhibitable-rpcs.c \ - claim-right.c transfer-right.c create-port-noinstall.c create-internal.c + claim-right.c transfer-right.c create-port-noinstall.c create-internal.c \ + interrupted.c LCLHDRS = ports.h installhdrs = ports.h +HURDLIBS= ihash OBJS = $(SRCS:.c=.o) notifyServer.o interruptServer.o - + MIGCOMSFLAGS = -prefix ports_ include ../Makeconf - -libports.so: $(foreach lib,ihash,\ - ../lib$(lib)/lib$(lib).so) diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c index 9b49579f..e439cb19 100644 --- a/libports/bucket-iterate.c +++ b/libports/bucket-iterate.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1995 Free Software Foundation, Inc. +/* Iterate a function over the ports in a bucket. + Copyright (C) 1995, 1999 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -22,13 +22,17 @@ #include <cthreads.h> #include <hurd/ihash.h> -/* This is obsecenely ineffecient. ihash and ports need to cooperate - more closely to do it effeciently. */ + +/* Internal entrypoint for both ports_bucket_iterate and ports_class_iterate. + If CLASS is non-null, call FUN only for ports in that class. */ error_t -ports_bucket_iterate (struct port_bucket *bucket, - error_t (*fun)(void *)) +_ports_bucket_class_iterate (struct port_bucket *bucket, + struct port_class *class, + error_t (*fun)(void *)) { - struct item + /* This is obscenely ineffecient. ihash and ports need to cooperate + more closely to do it efficiently. */ + struct item { struct item *next; void *p; @@ -36,22 +40,23 @@ ports_bucket_iterate (struct port_bucket *bucket, struct item *i, *nxt; error_t err; - error_t enqueue (void *pi) + mutex_lock (&_ports_lock); + HURD_IHASH_ITERATE (&bucket->htable, arg) { + struct port_info *const pi = arg; struct item *j; - - j = malloc (sizeof (struct item)); - j->next = list; - j->p = pi; - list = j; - ((struct port_info *)pi)->refcnt++; - return 0; + + if (class == 0 || pi->class == class) + { + j = malloc (sizeof (struct item)); + j->next = list; + j->p = pi; + list = j; + pi->refcnt++; + } } - - mutex_lock (&_ports_lock); - ihash_iterate (bucket->htable, enqueue); mutex_unlock (&_ports_lock); - + err = 0; for (i = list; i; i = nxt) { @@ -62,4 +67,11 @@ ports_bucket_iterate (struct port_bucket *bucket, free (i); } return err; -} +} + +error_t +ports_bucket_iterate (struct port_bucket *bucket, + error_t (*fun)(void *)) +{ + return _ports_bucket_class_iterate (bucket, 0, fun); +} diff --git a/libports/claim-right.c b/libports/claim-right.c index 2ddb3aaa..aef53bb7 100644 --- a/libports/claim-right.c +++ b/libports/claim-right.c @@ -1,5 +1,5 @@ /* Take a receive right away from a port - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996, 2001 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -20,33 +20,34 @@ #include "ports.h" +#include <assert.h> +#include <errno.h> #include <hurd/ihash.h> mach_port_t ports_claim_right (void *portstruct) { + error_t err; struct port_info *pi = portstruct; - mach_port_t ret; + mach_port_t ret = pi->port_right; - if (pi->port_right != MACH_PORT_NULL) + if (ret == MACH_PORT_NULL) + return ret; + + mutex_lock (&_ports_lock); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); + err = mach_port_move_member (mach_task_self (), ret, MACH_PORT_NULL); + assert_perror (err); + pi->port_right = MACH_PORT_NULL; + if (pi->flags & PORT_HAS_SENDRIGHTS) { - ret = pi->port_right; - - mutex_lock (&_ports_lock); - ihash_locp_remove (pi->bucket->htable, pi->hentry); - mach_port_move_member (mach_task_self (), ret, MACH_PORT_NULL); - pi->port_right = MACH_PORT_NULL; - if (pi->flags & PORT_HAS_SENDRIGHTS) - { - pi->flags &= ~PORT_HAS_SENDRIGHTS; - mutex_unlock (&_ports_lock); - ports_port_deref (pi); - } - else - mutex_unlock (&_ports_lock); + pi->flags &= ~PORT_HAS_SENDRIGHTS; + mutex_unlock (&_ports_lock); + ports_port_deref (pi); } else - ret = MACH_PORT_NULL; + mutex_unlock (&_ports_lock); + return ret; } diff --git a/libports/intern-external-port.c b/libports/class-iterate.c index 8ece48e4..e2a15173 100644 --- a/libports/intern-external-port.c +++ b/libports/class-iterate.c @@ -1,6 +1,5 @@ -/* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell. +/* Iterate a function over the ports in a class. + Copyright (C) 1999 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -16,22 +15,22 @@ 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. */ + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ #include "ports.h" +#include <cthreads.h> -/* Backward compatibility. */ -void *ports_intern_external_port (struct port_bucket *bucket, - mach_port_t port, - size_t size, - struct port_class *class) +error_t +ports_class_iterate (struct port_class *class, + error_t (*fun)(void *)) { - void *result; - if (ports_import_port (class, bucket, port, size, &result)) - result = 0; - return result; + mutex_lock (&_ports_lock); + if (class->ports != 0) + { + struct port_bucket *bucket = class->ports->bucket; + mutex_unlock (&_ports_lock); + return _ports_bucket_class_iterate (bucket, class, fun); + } + mutex_unlock (&_ports_lock); + return 0; } - -#include "linkwarn.h" -link_warning (ports_intern_external_port, - "ports_intern_external_port is obsolete; use ports_import_port") diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c index a94ab171..52e8f17b 100644 --- a/libports/complete-deallocate.c +++ b/libports/complete-deallocate.c @@ -30,7 +30,7 @@ _ports_complete_deallocate (struct port_info *pi) if (pi->port_right) { - ihash_locp_remove (pi->bucket->htable, pi->hentry); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); mach_port_mod_refs (mach_task_self (), pi->port_right, MACH_PORT_RIGHT_RECEIVE, -1); pi->port_right = MACH_PORT_NULL; diff --git a/libports/create-bucket.c b/libports/create-bucket.c index 1c3346e4..6be4bcad 100644 --- a/libports/create-bucket.c +++ b/libports/create-bucket.c @@ -1,5 +1,5 @@ /* Create a port bucket - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1997, 2001, 2003 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -19,7 +19,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ports.h" -#include <assert.h> +#include <stddef.h> +#include <errno.h> +#include <stdlib.h> #include <hurd/ihash.h> #include <cthreads.h> @@ -30,18 +32,28 @@ ports_create_bucket () error_t err; ret = malloc (sizeof (struct port_bucket)); - assert (ret); + if (! ret) + { + errno = ENOMEM; + return NULL; + } + 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); + if (err) + { + errno = err; + free (ret); + return NULL; + } + + hurd_ihash_init (&ret->htable, offsetof (struct port_info, hentry)); + ret->rpcs = ret->flags = ret->count = 0; 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 index 7db99ca1..12c8add9 100644 --- a/libports/create-class.c +++ b/libports/create-class.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995,2001 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -20,7 +20,7 @@ #include "ports.h" #include <stdlib.h> -#include <assert.h> +#include <errno.h> struct port_class * ports_create_class (void (*clean_routine)(void *), @@ -29,7 +29,12 @@ ports_create_class (void (*clean_routine)(void *), struct port_class *cl; cl = malloc (sizeof (struct port_class)); - assert (cl); + if (! cl) + { + errno = ENOMEM; + return NULL; + } + cl->clean_routine = clean_routine; cl->dropweak_routine = dropweak_routine; cl->flags = 0; diff --git a/libports/create-internal.c b/libports/create-internal.c index bc97ce62..7a9b1cb0 100644 --- a/libports/create-internal.c +++ b/libports/create-internal.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996,2001 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -48,7 +48,9 @@ _ports_create_port_internal (struct port_class *class, pi = malloc (size); if (! pi) { - mach_port_deallocate (mach_task_self (), port); + err = mach_port_mod_refs (mach_task_self (), port, + MACH_PORT_RIGHT_RECEIVE, -1); + assert_perror (err); return ENOMEM; } @@ -80,7 +82,7 @@ _ports_create_port_internal (struct port_class *class, goto loop; } - err = ihash_add (bucket->htable, port, pi, &pi->hentry); + err = hurd_ihash_add (&bucket->htable, port, pi); if (err) goto lose; @@ -94,7 +96,12 @@ _ports_create_port_internal (struct port_class *class, mutex_unlock (&_ports_lock); if (install) - mach_port_move_member (mach_task_self (), pi->port_right, bucket->portset); + { + err = mach_port_move_member (mach_task_self (), pi->port_right, + bucket->portset); + if (err) + goto lose_unlocked; + } *(void **)result = pi; return 0; @@ -103,7 +110,10 @@ _ports_create_port_internal (struct port_class *class, err = EINTR; lose: mutex_unlock (&_ports_lock); - mach_port_mod_refs (mach_task_self (), port, MACH_PORT_RIGHT_RECEIVE, -1); + lose_unlocked: + err = mach_port_mod_refs (mach_task_self (), port, + MACH_PORT_RIGHT_RECEIVE, -1); + assert_perror (err); free (pi); return err; diff --git a/libports/dead-name.c b/libports/dead-name.c index 07705563..de89ba6b 100644 --- a/libports/dead-name.c +++ b/libports/dead-name.c @@ -1,6 +1,6 @@ /* Handle various ports internal uses of dead-name notification - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1999 Free Software Foundation, Inc. Written by Miles Bader <miles@gnu.ai.mit.edu> diff --git a/libports/destroy-right.c b/libports/destroy-right.c index 704c0f57..327029a8 100644 --- a/libports/destroy-right.c +++ b/libports/destroy-right.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. +/* + Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -23,30 +23,29 @@ #include <hurd/ihash.h> #include <assert.h> -void +error_t ports_destroy_right (void *portstruct) { struct port_info *pi = portstruct; error_t err; - + if (pi->port_right != MACH_PORT_NULL) { mutex_lock (&_ports_lock); - ihash_locp_remove (pi->bucket->htable, pi->hentry); + hurd_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); } } -} - - + return 0; +} diff --git a/libports/end-rpc.c b/libports/end-rpc.c index d4d46e62..47fd1ae7 100644 --- a/libports/end-rpc.c +++ b/libports/end-rpc.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -38,12 +38,16 @@ ports_end_rpc (void *port, struct rpc_info *info) _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))) + if ((pi->flags & PORT_INHIBIT_WAIT) + || (pi->bucket->flags & PORT_BUCKET_INHIBIT_WAIT) + || (pi->class->flags & PORT_CLASS_INHIBIT_WAIT) + || (_ports_flags & _PORTS_INHIBIT_WAIT)) condition_broadcast (&_ports_block); + /* This removes the current thread's rpc (which should be INFO) from the + ports interrupted list. */ + ports_self_interrupted (); + /* Clear the cancellation flag for this thread since the current RPC is now finished anwhow. */ hurd_check_cancel (); diff --git a/libports/get-right.c b/libports/get-right.c index 0c5f13b7..95662f58 100644 --- a/libports/get-right.c +++ b/libports/get-right.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. +/* + Copyright (C) 1995,96,2000 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -23,14 +23,13 @@ #include <mach/notify.h> #include <assert.h> -static volatile error_t gdb_loses = 0; - mach_port_t ports_get_right (void *port) { struct port_info *pi = port; mach_port_t foo; - + error_t err; + mutex_lock (&_ports_lock); if (pi->port_right == MACH_PORT_NULL) @@ -38,23 +37,23 @@ ports_get_right (void *port) mutex_unlock (&_ports_lock); return MACH_PORT_NULL; } - + pi->mscount++; if ((pi->flags & PORT_HAS_SENDRIGHTS) == 0) { pi->flags |= PORT_HAS_SENDRIGHTS; pi->refcnt++; - gdb_loses = - 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, &foo); - assert_perror (gdb_loses); + err = 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, + &foo); + assert_perror (err); if (foo != MACH_PORT_NULL) mach_port_deallocate (mach_task_self (), foo); } mutex_unlock (&_ports_lock); return pi->port_right; } - - diff --git a/libports/allocate-port.c b/libports/get-send-right.c index 61e093c8..3e00276c 100644 --- a/libports/allocate-port.c +++ b/libports/get-send-right.c @@ -1,6 +1,5 @@ -/* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell. +/* ports_get_send_right -- get a send right to a ports object + Copyright (C) 2000 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -19,20 +18,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ports.h" +#include <assert.h> -/* Backward compatibility. */ -void *ports_allocate_port (struct port_bucket *bucket, - size_t size, - struct port_class *class) +mach_port_t +ports_get_send_right (void *port) { - void *result; - if (ports_create_port (class, bucket, size, &result)) - result = 0; - return result; -} + error_t err; + mach_port_t right; + right = ports_get_right (port); + if (right == MACH_PORT_NULL) + return MACH_PORT_NULL; -#include "linkwarn.h" + err = mach_port_insert_right (mach_task_self (), + right, right, MACH_MSG_TYPE_MAKE_SEND); + assert_perror (err); -link_warning (ports_allocate_port, - "ports_allocate_port is obsolete; use ports_create_port instead") + return right; +} diff --git a/libports/import-port.c b/libports/import-port.c index b958245f..d7a62960 100644 --- a/libports/import-port.c +++ b/libports/import-port.c @@ -76,7 +76,7 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, goto loop; } - err = ihash_add (bucket->htable, port, pi, &pi->hentry); + err = hurd_ihash_add (&bucket->htable, port, pi); if (err) goto lose; diff --git a/libports/inhibit-all-rpcs.c b/libports/inhibit-all-rpcs.c index 13aa62c6..9a72f83e 100644 --- a/libports/inhibit-all-rpcs.c +++ b/libports/inhibit-all-rpcs.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -36,19 +36,25 @@ ports_inhibit_all_rpcs () { struct port_bucket *bucket; int this_one = 0; - error_t interruptor (void *portstruct) - { - struct rpc_info *rpc; - struct port_info *pi = portstruct; - - for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) - if (hurd_thread_cancel (rpc->thread) == EINTR) - this_one = 1; - return 0; - } for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) - ihash_iterate (bucket->htable, interruptor); + { + HURD_IHASH_ITERATE (&bucket->htable, portstruct) + { + struct rpc_info *rpc; + struct port_info *pi = portstruct; + + for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) + { + /* Avoid cancelling the calling thread if it's currently + handling a RPC. */ + if (rpc->thread == hurd_thread_self ()) + this_one = 1; + else + hurd_thread_cancel (rpc->thread); + } + } + } while (_ports_total_rpcs > this_one) { @@ -70,5 +76,3 @@ ports_inhibit_all_rpcs () return err; } - - diff --git a/libports/inhibit-bucket-rpcs.c b/libports/inhibit-bucket-rpcs.c index a04906ff..7fc55d31 100644 --- a/libports/inhibit-bucket-rpcs.c +++ b/libports/inhibit-bucket-rpcs.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -35,18 +35,22 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) else { int this_one = 0; - error_t interruptor (void *portstruct) + + HURD_IHASH_ITERATE (&bucket->htable, portstruct) { struct rpc_info *rpc; struct port_info *pi = portstruct; for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) - if (hurd_thread_cancel (rpc->thread) == EINTR) - this_one = 1; - return 0; + { + /* Avoid cancelling the calling thread. */ + if (rpc->thread == hurd_thread_self ()) + this_one = 1; + else + hurd_thread_cancel (rpc->thread); + } } - ihash_iterate (bucket->htable, interruptor); while (bucket->rpcs > this_one) { diff --git a/libports/inhibit-class-rpcs.c b/libports/inhibit-class-rpcs.c index 00b9b361..951de4bf 100644 --- a/libports/inhibit-class-rpcs.c +++ b/libports/inhibit-class-rpcs.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -39,8 +39,13 @@ ports_inhibit_class_rpcs (struct port_class *class) for (pi = class->ports; pi; pi = pi->next) for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) - if (hurd_thread_cancel (rpc->thread) == EINTR) - this_one = 1; + { + /* Avoid cancelling the calling thread. */ + if (rpc->thread == hurd_thread_self ()) + this_one = 1; + else + hurd_thread_cancel (rpc->thread); + } while (class->rpcs > this_one) { diff --git a/libports/inhibit-port-rpcs.c b/libports/inhibit-port-rpcs.c index 4ec5d853..02a3b462 100644 --- a/libports/inhibit-port-rpcs.c +++ b/libports/inhibit-port-rpcs.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -38,8 +38,13 @@ ports_inhibit_port_rpcs (void *portstruct) struct rpc_info *this_rpc = 0; for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) - if (hurd_thread_cancel (rpc->thread) == EINTR) - this_rpc = rpc; + { + /* Avoid cancelling the calling thread. */ + if (rpc->thread == hurd_thread_self ()) + this_rpc = rpc; + else + hurd_thread_cancel (rpc->thread); + } while (pi->current_rpcs /* If this thread's RPC is the only one left, it doesn't count. */ diff --git a/libports/init.c b/libports/init.c index 44c8bdd4..7d4d16fd 100644 --- a/libports/init.c +++ b/libports/init.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 2001 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -23,6 +23,6 @@ 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; +struct port_bucket *_ports_all_buckets; +int _ports_total_rpcs; +int _ports_flags; diff --git a/libports/interrupt-notified-rpcs.c b/libports/interrupt-notified-rpcs.c index 061d3d87..bdfef977 100644 --- a/libports/interrupt-notified-rpcs.c +++ b/libports/interrupt-notified-rpcs.c @@ -1,8 +1,8 @@ /* Handle interruping rpcs because of notification - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 2001 Free Software Foundation, Inc. - Written by Miles Bader <miles@gnu.ai.mit.edu> + Written by Miles Bader <miles@gnu.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -21,11 +21,11 @@ #include "ports.h" /* A linked list of ports for which notification has been requested. */ -struct ports_notify *_ports_notifications = 0; +struct ports_notify *_ports_notifications; /* Free lists for notify structures. */ -struct ports_notify *_ports_free_ports_notifies = 0; -struct rpc_notify *_ports_free_rpc_notifies = 0; +struct ports_notify *_ports_free_ports_notifies; +struct rpc_notify *_ports_free_rpc_notifies; /* Interrupt any rpcs on OBJECT that have requested such. */ void diff --git a/libports/interrupt-on-notify.c b/libports/interrupt-on-notify.c index 4f8c1344..42ae4884 100644 --- a/libports/interrupt-on-notify.c +++ b/libports/interrupt-on-notify.c @@ -1,8 +1,8 @@ /* Mark an rpc to be interrupted when a port dies - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 96, 99 Free Software Foundation, Inc. - Written by Miles Bader <miles@gnu.ai.mit.edu> + Written by Miles Bader <miles@gnu.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ports.h" +#include <assert.h> /* Arrange for hurd_cancel to be called on RPC's thread if OBJECT gets notified that any of the things in COND have happened to PORT. RPC should be an @@ -175,11 +176,9 @@ ports_interrupt_self_on_notification (void *object, break; mutex_unlock (&_ports_lock); - if (rpc) - /* We don't have to worry about RPC going away after we dropped the lock - because we're that thread, and we're still here. */ - return ports_interrupt_rpc_on_notification (object, rpc, port, what); - else - /* This thread isn't in an rpc! */ - return EIEIO; + assert (rpc); + + /* We don't have to worry about RPC going away after we dropped the lock + because we're that thread, and we're still here. */ + return ports_interrupt_rpc_on_notification (object, rpc, port, what); } diff --git a/libports/interrupt-rpcs.c b/libports/interrupt-rpcs.c index 95eeed4b..7c28ff2c 100644 --- a/libports/interrupt-rpcs.c +++ b/libports/interrupt-rpcs.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -31,7 +31,10 @@ ports_interrupt_rpcs (void *portstruct) mutex_lock (&_ports_lock); for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) - hurd_thread_cancel (rpc->thread); + { + hurd_thread_cancel (rpc->thread); + _ports_record_interruption (rpc); + } mutex_unlock (&_ports_lock); } diff --git a/libports/interrupted.c b/libports/interrupted.c new file mode 100644 index 00000000..e4cb2fc2 --- /dev/null +++ b/libports/interrupted.c @@ -0,0 +1,75 @@ +/* Keeping track of thread interruption + + Copyright (C) 1997 Free Software Foundation, Inc. + Written by Miles Bader <miles@gnu.ai.mit.edu> + 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "ports.h" + +static spin_lock_t interrupted_lock = SPIN_LOCK_INITIALIZER; + +/* True if some active rpc has been interrupted. */ +static struct rpc_info *interrupted = 0; + +/* If the current thread's rpc has been interrupted with + ports_interrupt_rpcs, return true (and clear the interrupted flag). */ +int +ports_self_interrupted () +{ + struct rpc_info **rpc_p, *rpc; + thread_t self = hurd_thread_self (); + + spin_lock (&interrupted_lock); + for (rpc_p = &interrupted; *rpc_p; rpc_p = &rpc->interrupted_next) + { + rpc = *rpc_p; + if (rpc->thread == self) + { + *rpc_p = rpc->interrupted_next; + spin_unlock (&interrupted_lock); + rpc->interrupted_next = 0; + return 1; + } + } + spin_unlock (&interrupted_lock); + + return 0; +} + +/* Add RPC to the list of rpcs that have been interrupted. */ +void +_ports_record_interruption (struct rpc_info *rpc) +{ + struct rpc_info *i; + + spin_lock (&interrupted_lock); + + /* See if RPC is already in the interrupted list. */ + for (i = interrupted; i; i = i->interrupted_next) + if (i == rpc) + /* Yup, it is, so just leave it there. */ + { + spin_unlock (&interrupted_lock); + return; + } + + /* Nope, put it at the beginning. */ + rpc->interrupted_next = interrupted; + interrupted = rpc; + + spin_unlock (&interrupted_lock); +} diff --git a/libports/lookup-port.c b/libports/lookup-port.c index d0ee8d00..8eb98a12 100644 --- a/libports/lookup-port.c +++ b/libports/lookup-port.c @@ -32,11 +32,11 @@ ports_lookup_port (struct port_bucket *bucket, mutex_lock (&_ports_lock); if (bucket) - pi = ihash_find (bucket->htable, port); + pi = hurd_ihash_find (&bucket->htable, port); else for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) { - pi = ihash_find (bucket->htable, port); + pi = hurd_ihash_find (&bucket->htable, port); if (pi) break; } diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c index 2f3f344f..82fa2ac6 100644 --- a/libports/manage-multithread.c +++ b/libports/manage-multithread.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -29,8 +29,7 @@ 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) + void (*hook)()) { volatile int nreqthreads; volatile int totalthreads; @@ -61,6 +60,7 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, assert (nreqthreads); nreqthreads--; if (nreqthreads == 0) + /* No thread would be listening for requests, spawn one. */ spawn = 1; spin_unlock (&lock); @@ -123,10 +123,8 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, int timeout; error_t err; - if (wire_threads) - thread_wire (wire_threads, hurd_thread_self (), 1); - if (wire_cthreads) - cthread_wire (); + if (hook) + (*hook) (); if (master) timeout = global_timeout; @@ -153,6 +151,12 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, else { spin_lock (&lock); + if (nreqthreads == 1) + { + /* No other thread is listening for requests, continue. */ + spin_unlock (&lock); + goto startover; + } nreqthreads--; totalthreads--; spin_unlock (&lock); @@ -160,12 +164,6 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, return 0; } - /* Wire this because hurd_thread_cancel will not interoperate - cleanly with cthreads cleverness yet. */ - wire_cthreads = 1; - - thread_timeout = global_timeout = 0; /* XXX */ - nreqthreads = 1; totalthreads = 1; thread_function (1); diff --git a/libports/manage-one-thread.c b/libports/manage-one-thread.c index 57b8a9a9..4ea740b2 100644 --- a/libports/manage-one-thread.c +++ b/libports/manage-one-thread.c @@ -69,7 +69,7 @@ ports_manage_port_operations_one_thread (struct port_bucket *bucket, } else { - /* No need to check cancel threshhold here, because + /* No need to check cancel threshold here, because in a single threaded server the cancel is always handled in order. */ status = demuxer (inp, outheadp); diff --git a/libports/notify-dead-name.c b/libports/notify-dead-name.c index 24e34674..c67145d1 100644 --- a/libports/notify-dead-name.c +++ b/libports/notify-dead-name.c @@ -1,6 +1,6 @@ /* Dead name notification - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1999 Free Software Foundation, Inc. Written by Miles Bader <miles@gnu.ai.mit.edu> @@ -29,5 +29,9 @@ ports_do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_name) return EOPNOTSUPP; ports_dead_name (pi, dead_name); ports_port_deref (pi); + + /* Drop gratuitous extra reference that the notification creates. */ + mach_port_deallocate (mach_task_self (), dead_name); + return 0; } diff --git a/libports/port-deref.c b/libports/port-deref.c index a1238315..1ded45d9 100644 --- a/libports/port-deref.c +++ b/libports/port-deref.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 2001 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -32,11 +32,11 @@ ports_port_deref (void *portstruct) mutex_lock (&_ports_lock); - if (pi->refcnt == 1 && pi->weakrefcnt && !trieddroppingweakrefs) + if (pi->refcnt == 1 && pi->weakrefcnt + && pi->class->dropweak_routine && !trieddroppingweakrefs) { mutex_unlock (&_ports_lock); - if (pi->class->dropweak_routine) - (*pi->class->dropweak_routine) (pi); + (*pi->class->dropweak_routine) (pi); trieddroppingweakrefs = 1; goto retry; } diff --git a/libports/ports.h b/libports/ports.h index 2d52daa4..9a5ccbc2 100644 --- a/libports/ports.h +++ b/libports/ports.h @@ -1,5 +1,5 @@ /* Ports library for server construction - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1993,94,95,96,97,99,2000 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -24,6 +24,7 @@ #include <mach.h> #include <stdlib.h> #include <hurd.h> +#include <hurd/ihash.h> #include <mach/notify.h> /* These are global values for common flags used in the various structures. @@ -45,7 +46,7 @@ struct port_info mach_port_t port_right; struct rpc_info *current_rpcs; struct port_bucket *bucket; - void **hentry; + hurd_ihash_locp_t hentry; struct port_info *next, **prevp; /* links on port_class list */ }; /* FLAGS above are the following: */ @@ -57,7 +58,7 @@ struct port_info struct port_bucket { mach_port_t portset; - struct ihash *htable; + struct hurd_ihash htable; int rpcs; int flags; int count; @@ -92,6 +93,7 @@ struct rpc_info thread_t thread; struct rpc_info *next, **prevp; struct rpc_notify *notifies; + struct rpc_info *interrupted_next; }; /* An rpc has requested interruption on a port notification. */ @@ -162,7 +164,19 @@ error_t ports_create_port (struct port_class *class, struct port_bucket *bucket, size_t size, void *result); - + +/* Just like ports_create_port, except don't actually put the port + into the portset underlying BUCKET. This is intended to be used + for cases where the port right must be given out before the port is + fully initialized; with this call you are guaranteed that no RPC + service will occur on the port until you have finished initializing + it and installed it into the portset yourself. */ +error_t +ports_create_port_noinstall (struct port_class *class, + struct port_bucket *bucket, + size_t size, + void *result); + /* For an existing RECEIVE right, create and return in RESULT a new port structure; BUCKET, SIZE, and CLASS args are as for ports_create_port. */ error_t ports_import_port (struct port_class *class, @@ -180,12 +194,12 @@ void ports_reallocate_from_external (void *port, mach_port_t receive); /* Destroy the receive right currently associated with PORT. After this call, ports_reallocate_port and ports_reallocate_from_external - may not be used. */ -void ports_destroy_right (void *port); + may not be used. Always returns 0, for convenient use as an iterator. */ +error_t ports_destroy_right (void *port); /* Return the receive right currently associated with PORT. The effects on PORT are the same as in ports_destroy_right, except that the receive - right itself is not affected. Note that in multi-threaded servers, + right itself is not affected. Note that in multi-threaded servers, messages might already have been dequeued for this port before it gets removed from the portset; such messages will get EOPNOTSUPP errors. */ mach_port_t ports_claim_right (void *port); @@ -196,20 +210,25 @@ mach_port_t ports_claim_right (void *port); were called. */ error_t ports_transfer_right (void *topt, void *frompt); -/* Return the name of the receive right associated with PORT. The user - is responsible for creating an ordinary send right from this name. */ +/* Return the name of the receive right associated with PORT. This assumes + that send rights will shortly be created, and arranges for notifications + accordingly. The user is responsible for creating an ordinary send + right from this name. */ mach_port_t ports_get_right (void *port); +/* This convenience function uses ports_get_right, and + deals with the creation of a send right as well. */ +mach_port_t ports_get_send_right (void *port); /* Reference counting */ - + /* Look up PORT and return the associated port structure, allocating a reference. If the call fails, return 0. If BUCKET is nonzero, then it specifies a bucket to search; otherwise all buckets will be searched. If CLASS is nonzero, then the lookup will fail if PORT is not in CLASS. */ -void *ports_lookup_port (struct port_bucket *bucket, +void *ports_lookup_port (struct port_bucket *bucket, mach_port_t port, struct port_class *class); /* Allocate another reference to PORT. */ @@ -238,7 +257,7 @@ int ports_count_class (struct port_class *class); of ports currently in BUCKET. */ int ports_count_bucket (struct port_bucket *bucket); -/* Permit suspended port creation (blocked by ports_count_class) +/* Permit suspended port creation (blocked by ports_count_class) to continue. */ void ports_enable_class (struct port_class *class); @@ -250,16 +269,23 @@ void ports_enable_bucket (struct port_bucket *bucket); error_t ports_bucket_iterate (struct port_bucket *bucket, error_t (*fun)(void *port)); +/* Call FUN once for each port in CLASS. */ +error_t ports_class_iterate (struct port_class *class, + error_t (*fun)(void *port)); +/* Internal entrypoint for above two. */ +error_t _ports_bucket_class_iterate (struct port_bucket *bucket, + struct port_class *class, + error_t (*fun)(void *port)); /* RPC management */ - + /* Type of MiG demuxer routines. */ -typedef int (*ports_demuxer_type)(mach_msg_header_t *inp, +typedef int (*ports_demuxer_type)(mach_msg_header_t *inp, mach_msg_header_t *outp); -/* Call this when an RPC is beginning on PORT. INFO should be - allocated by the caller and will be used to hold dynamic state. +/* Call this when an RPC is beginning on PORT. INFO should be + allocated by the caller and will be used to hold dynamic state. If this RPC should be abandoned, return EDIED; otherwise we return zero. */ error_t ports_begin_rpc (void *port, mach_msg_id_t msg_id, @@ -281,21 +307,17 @@ void ports_manage_port_operations_one_thread(struct port_bucket *bucket, for each incoming message. Return if GLOBAL_TIMEOUT is nonzero and no messages have been receieved for GLOBAL_TIMEOUT milliseconds. Create threads as necessary to handle incoming messages so that no - port is starved because of sluggishness on another port. All - threads created (and the calling thread) will be wired with - cthread_wire if WIRE_CTHREADS is non-zero. All threads created - (and the calling thread) will be wired with thread_wire if - WIRE_THREADS is non-zero (it must be the priviliged host port in - order to succeed). If LOCAL_TIMEOUT is non-zero, then individual - threads will die off if they handle no incoming messages for - LOCAL_TIMEOUT milliseconds. */ + port is starved because of sluggishness on another port. If + LOCAL_TIMEOUT is non-zero, then individual threads will die off if + they handle no incoming messages for LOCAL_TIMEOUT milliseconds. + HOOK (if not null) will be called in each new thread immediately + after it is created. */ 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); - + void (*hook)(void)); + /* Interrupt any pending RPC on PORT. Wait for all pending RPC's to finish, and then block any new RPC's starting on that port. */ error_t ports_inhibit_port_rpcs (void *port); @@ -325,6 +347,13 @@ void ports_resume_all_rpcs (void); /* Cancel (with thread_cancel) any RPC's in progress on PORT. */ void ports_interrupt_rpcs (void *port); +/* If the current thread's rpc has been interrupted with + ports_interrupt_rpcs, return true (and clear the interrupted flag). */ +int ports_self_interrupted (); + +/* Add RPC to the list of rpcs that have been interrupted. */ +void _ports_record_interruption (struct rpc_info *rpc); + /* Arrange for hurd_cancel to be called on RPC's thread if OBJECT gets notified that any of the things in COND have happened to PORT. RPC should be an rpc on OBJECT. */ @@ -363,7 +392,7 @@ extern kern_return_t /* A default interrupt server */ int ports_interrupt_server (mach_msg_header_t *, mach_msg_header_t *); -extern kern_return_t ports_S_interrupt_operation (mach_port_t, +extern kern_return_t ports_S_interrupt_operation (mach_port_t, mach_port_seqno_t); /* Private data */ @@ -376,5 +405,7 @@ extern int _ports_flags; #define _PORTS_BLOCKED PORTS_BLOCKED #define _PORTS_INHIBIT_WAIT PORTS_INHIBIT_WAIT void _ports_complete_deallocate (struct port_info *); +error_t _ports_create_port_internal (struct port_class *, struct port_bucket *, + size_t, void *, int); #endif diff --git a/libports/reallocate-from-external.c b/libports/reallocate-from-external.c index 80b2905e..ebddd9f7 100644 --- a/libports/reallocate-from-external.c +++ b/libports/reallocate-from-external.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2003 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -44,7 +44,7 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) MACH_PORT_RIGHT_RECEIVE, -1); assert_perror (err); - ihash_locp_remove (pi->bucket->htable, pi->hentry); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); if ((pi->flags & PORT_HAS_SENDRIGHTS) && !stat.mps_srights) { @@ -61,7 +61,7 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) pi->cancel_threshold = 0; pi->mscount = stat.mps_mscount; - ihash_add (pi->bucket->htable, receive, pi, &pi->hentry); + hurd_ihash_add (&pi->bucket->htable, receive, pi); mutex_unlock (&_ports_lock); mach_port_move_member (mach_task_self (), receive, pi->bucket->portset); diff --git a/libports/reallocate-port.c b/libports/reallocate-port.c index 35dd4883..23898e88 100644 --- a/libports/reallocate-port.c +++ b/libports/reallocate-port.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2001, 2003 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -37,7 +37,7 @@ ports_reallocate_port (void *portstruct) MACH_PORT_RIGHT_RECEIVE, -1); assert_perror (err); - ihash_locp_remove (pi->bucket->htable, pi->hentry); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &pi->port_right); @@ -49,11 +49,12 @@ ports_reallocate_port (void *portstruct) } pi->cancel_threshold = 0; pi->mscount = 0; - ihash_add (pi->bucket->htable, pi->port_right, pi, &pi->hentry); + hurd_ihash_add (&pi->bucket->htable, pi->port_right, pi); mutex_unlock (&_ports_lock); - mach_port_move_member (mach_task_self (), pi->port_right, - pi->bucket->portset); + err = mach_port_move_member (mach_task_self (), pi->port_right, + pi->bucket->portset); + assert_perror (err); if (dropref) ports_port_deref (pi); diff --git a/libports/resume-all-rpcs.c b/libports/resume-all-rpcs.c index fa978c1e..452da3b2 100644 --- a/libports/resume-all-rpcs.c +++ b/libports/resume-all-rpcs.c @@ -28,7 +28,7 @@ ports_resume_all_rpcs () mutex_lock (&_ports_lock); assert (_ports_flags & _PORTS_INHIBITED); _ports_flags &= ~_PORTS_INHIBITED; - if (_ports_flags | _PORTS_BLOCKED) + if (_ports_flags & _PORTS_BLOCKED) { _ports_flags &= ~_PORTS_BLOCKED; condition_broadcast (&_ports_block); diff --git a/libports/resume-bucket-rpcs.c b/libports/resume-bucket-rpcs.c index 9d968874..59cc75a4 100644 --- a/libports/resume-bucket-rpcs.c +++ b/libports/resume-bucket-rpcs.c @@ -28,7 +28,7 @@ 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) + if (bucket->flags & PORT_BUCKET_BLOCKED) { bucket->flags &= ~PORT_BUCKET_BLOCKED; condition_broadcast (&_ports_block); diff --git a/libports/resume-class-rpcs.c b/libports/resume-class-rpcs.c index 4b35f26c..a4191747 100644 --- a/libports/resume-class-rpcs.c +++ b/libports/resume-class-rpcs.c @@ -28,7 +28,7 @@ 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) + if (class->flags & PORT_CLASS_BLOCKED) { class->flags &= ~PORT_CLASS_BLOCKED; condition_broadcast (&_ports_block); diff --git a/libports/resume-port-rpcs.c b/libports/resume-port-rpcs.c index 563c9adc..e9e30fbd 100644 --- a/libports/resume-port-rpcs.c +++ b/libports/resume-port-rpcs.c @@ -31,7 +31,7 @@ ports_resume_port_rpcs (void *portstruct) assert (pi->flags & PORT_INHIBITED); pi->flags &= ~PORT_INHIBITED; - if (pi->flags | PORT_BLOCKED) + if (pi->flags & PORT_BLOCKED) { pi->flags &= ~PORT_BLOCKED; condition_broadcast (&_ports_block); diff --git a/libports/transfer-right.c b/libports/transfer-right.c index d5844ea2..e7b0ff55 100644 --- a/libports/transfer-right.c +++ b/libports/transfer-right.c @@ -1,5 +1,5 @@ /* Transfer the receive right from one port structure to another - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996, 2003 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -20,6 +20,7 @@ #include "ports.h" +#include <assert.h> #include <hurd/ihash.h> error_t @@ -40,7 +41,7 @@ ports_transfer_right (void *tostruct, port = frompi->port_right; if (port != MACH_PORT_NULL) { - ihash_locp_remove (frompi->bucket->htable, frompi->hentry); + hurd_ihash_locp_remove (&frompi->bucket->htable, frompi->hentry); frompi->port_right = MACH_PORT_NULL; if (frompi->flags & PORT_HAS_SENDRIGHTS) { @@ -53,9 +54,10 @@ ports_transfer_right (void *tostruct, /* Destroy the existing right in TOPI. */ if (topi->port_right != MACH_PORT_NULL) { - ihash_locp_remove (topi->bucket->htable, topi->hentry); + hurd_ihash_locp_remove (&topi->bucket->htable, topi->hentry); err = mach_port_mod_refs (mach_task_self (), topi->port_right, MACH_PORT_RIGHT_RECEIVE, -1); + assert_perror (err); if ((topi->flags & PORT_HAS_SENDRIGHTS) && !hassendrights) { dereftopi = 1; @@ -75,9 +77,13 @@ ports_transfer_right (void *tostruct, if (port) { - ihash_add (topi->bucket->htable, port, topi, &topi->hentry); + hurd_ihash_add (&topi->bucket->htable, port, topi); if (topi->bucket != frompi->bucket) - mach_port_move_member (mach_task_self (), port, topi->bucket->portset); + { + err = mach_port_move_member (mach_task_self (), port, + topi->bucket->portset); + assert_perror (err); + } } mutex_unlock (&_ports_lock); |