summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-12-05 04:54:00 +0000
committerRoland McGrath <roland@gnu.org>1995-12-05 04:54:00 +0000
commitbe50ce941b64a58069150e0513cd1f8fd87c3eaa (patch)
treeaeac14baa5398c5771b8ebaf1e2fcc1b3065c3b3
parent926c0309375fbca61f21211cdf4a5f5662b09f55 (diff)
(main): Request no-senders notification on pseudo_master_device_port.
Deallocate our send right to it when we no longer need it. (ds_device_read_inband): Unlock readlock properly. (do_mach_notify_no_senders): Exit only when both pseudo_console and pseudo_master_device_port have no senders.
-rw-r--r--boot/boot.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/boot/boot.c b/boot/boot.c
index f9d7c13f..7daf66c2 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -637,6 +637,12 @@ main (int argc, char **argv, char **envp)
MACH_MSG_TYPE_MAKE_SEND);
mach_port_move_member (mach_task_self (), pseudo_master_device_port,
receive_set);
+ mach_port_request_notification (mach_task_self (), pseudo_master_device_port,
+ MACH_NOTIFY_NO_SENDERS, 1,
+ pseudo_master_device_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE, &foo);
+ if (foo != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), foo);
mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
&pseudo_console);
@@ -751,6 +757,8 @@ main (int argc, char **argv, char **envp)
free (buf);
}
+ mach_port_deallocate (mach_task_self (), pseudo_master_device_port);
+
cthread_detach (cthread_fork ((cthread_fn_t) msg_thread,
(any_t) 0));
@@ -1468,13 +1476,13 @@ ds_device_read_inband (device_t device,
if (avail)
{
*datalen = read (0, data, bytes_wanted);
- spin_lock (&readlock);
+ spin_unlock (&readlock);
sigsetmask (mask);
return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
}
else
{
- spin_lock (&readlock);
+ spin_unlock (&readlock);
queue_read (DEV_READI, reply_port, reply_type, bytes_wanted);
sigsetmask (mask);
return MIG_NO_REPLY;
@@ -1589,20 +1597,35 @@ kern_return_t
do_mach_notify_no_senders (mach_port_t notify,
mach_port_mscount_t mscount)
{
+ static int no_console;
mach_port_t foo;
+ if (notify == pseudo_master_device_port)
+ {
+ if (no_console)
+ goto bye;
+ pseudo_master_device_port = MACH_PORT_NULL;
+ return 0;
+ }
if (notify == pseudo_console)
{
- if (mscount == console_mscount)
+ if (mscount == console_mscount &&
+ pseudo_master_device_port == MACH_PORT_NULL)
{
+ bye:
restore_termstate ();
-write (2, "bye\n", 4);
+ write (2, "bye\n", 4);
uxexit (0);
}
else
{
+ no_console = (mscount == console_mscount);
+
mach_port_request_notification (mach_task_self (), pseudo_console,
MACH_NOTIFY_NO_SENDERS,
- console_mscount, pseudo_console,
+ console_mscount == mscount
+ ? mscount + 1
+ : console_mscount,
+ pseudo_console,
MACH_MSG_TYPE_MAKE_SEND_ONCE, &foo);
if (foo != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self (), foo);