diff options
Diffstat (limited to 'proc/msg.c')
-rw-r--r-- | proc/msg.c | 55 |
1 files changed, 36 insertions, 19 deletions
@@ -1,5 +1,5 @@ /* Message port manipulations - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1999, 2001 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -50,7 +50,6 @@ S_proc_setmsgport (struct proc *p, mach_port_t *oldmsgport, mach_msg_type_name_t *oldmsgport_type) { - mach_port_t foo; if (!p) return EOPNOTSUPP; @@ -63,12 +62,6 @@ S_proc_setmsgport (struct proc *p, prociterate (check_message_return, p); p->p_checkmsghangs = 0; - mach_port_request_notification (mach_task_self (), msgport, - MACH_NOTIFY_DEAD_NAME, 1, p->p_pi.port_right, - MACH_MSG_TYPE_MAKE_SEND_ONCE, &foo); - if (foo) - mach_port_deallocate (mach_task_self (), foo); - if (p == startup_proc) /* Init is single threaded, so we can't delay our reply for the essential task RPC; spawn a thread to do it. */ @@ -89,6 +82,32 @@ check_message_dying (struct proc *p, struct proc *dyingp) } } +/* Check if the message port of process P has died. Return nonzero if + this has indeed happened. */ +int +check_msgport_death (struct proc *p) +{ + /* Only check if the message port passed away, if we know that it + was ever alive. */ + if (p->p_msgport != MACH_PORT_NULL) + { + mach_port_type_t type; + error_t err; + + err = mach_port_type (mach_task_self (), p->p_msgport, &type); + if (err || (type & MACH_PORT_TYPE_DEAD_NAME)) + { + /* The port appears to be dead; throw it away. */ + mach_port_deallocate (mach_task_self (), p->p_msgport); + p->p_msgport = MACH_PORT_NULL; + p->p_deadmsg = 1; + return 1; + } + } + + return 0; +} + error_t S_proc_getmsgport (struct proc *callerp, mach_port_t reply_port, @@ -97,11 +116,14 @@ S_proc_getmsgport (struct proc *callerp, mach_port_t *msgport) { int cancel; - struct proc *p = pid_find_allow_zombie (pid); + struct proc *p; if (!callerp) return EOPNOTSUPP; - + + p = pid_find_allow_zombie (pid); + +restart: while (p && p->p_deadmsg && !p->p_dead) { callerp->p_msgportwait = 1; @@ -119,15 +141,10 @@ S_proc_getmsgport (struct proc *callerp, if (!p) return ESRCH; + if (check_msgport_death (p)) + goto restart; + *msgport = p->p_msgport; - return 0; -} -void -message_port_dead (struct proc *p) -{ - mach_port_deallocate (mach_task_self (), p->p_msgport); - p->p_msgport = MACH_PORT_NULL; - p->p_deadmsg = 1; + return 0; } - |