summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-12-11 04:34:06 +0000
committerMiles Bader <miles@gnu.org>1995-12-11 04:34:06 +0000
commit0b2b7a65c86306c656ac4809f310543c3d1b58d6 (patch)
treef51a5f72c7807f568c2eef19647f1593d2e71052 /boot
parentc4778301f3628f7fac367a4e6416d5df633ffc2a (diff)
(should_read): New variable.
(read_reply): Set SHOULD_READ before attempting lock. Use spin_try_lock() instead of spin_lock(), and abort if we can't get it. Clear SHOULD_READ after getting the lock. (ds_device_read, ds_device_read_inband, S_io_read): Call unlock_readlock instead of directly unlocking READLOCK. Don't block SIGIO. (unlock_readlock): New function. (main): Don't trap SIGMSG & SIGEMSG. (SIGMSG, SIGEMSG): Macros deleted.
Diffstat (limited to 'boot')
-rw-r--r--boot/boot.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/boot/boot.c b/boot/boot.c
index 7daf66c2..192f4053 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -263,8 +263,7 @@ struct sgttyb
#define SIGIO 23
-#define SIGEMSG 30
-#define SIGMSG 31
+
struct sigvec
{
void (*sv_handler)();
@@ -370,11 +369,11 @@ request_server (mach_msg_header_t *inp,
}
else
#endif
- return (io_server (inp, outp)
- || device_server (inp, outp)
- || notify_server (inp, outp)
- || term_server (inp, outp)
-/* || tioctl_server (inp, outp) */);
+ return (io_server (inp, outp)
+ || device_server (inp, outp)
+ || notify_server (inp, outp)
+ || term_server (inp, outp)
+ /* || tioctl_server (inp, outp) */);
}
vm_address_t
@@ -737,8 +736,6 @@ main (int argc, char **argv, char **envp)
init_termstate ();
ioctl (0, FIOASYNC, &foo);
sigvec (SIGIO, &vec, 0);
- sigvec (SIGMSG, &vec, 0);
- sigvec (SIGEMSG, &vec, 0);
/* The boot script has now been parsed into internal data structures.
Now execute its directives. */
@@ -1009,6 +1006,10 @@ queue_read (enum read_type type,
spin_unlock (&queuelock);
}
+/* TRUE if there's data available on stdin, which should be used to satisfy
+ console read requests. */
+static int should_read = 0;
+
/* Reply to a queued read. */
void
read_reply ()
@@ -1018,7 +1019,16 @@ read_reply ()
char * buf;
int amtread;
- spin_lock (&readlock);
+ /* By forcing SHOULD_READ to true before trying the lock, we ensure that
+ either we get the lock ourselves or that whoever currently holds the
+ lock will service this read when he unlocks it. */
+ should_read = 1;
+ if (! spin_try_lock (&readlock))
+ return;
+
+ /* Since we're commited to servicing the read, no one else need do so. */
+ should_read = 0;
+
ioctl (0, FIONREAD, &avail);
if (!avail)
{
@@ -1081,6 +1091,16 @@ read_reply ()
free (qr);
}
+/* Unlock READLOCK, and also service any new read requests that it was
+ blocking. */
+static void
+unlock_readlock ()
+{
+ spin_unlock (&readlock);
+ while (should_read)
+ read_reply ();
+}
+
/*
* Handle bootstrap requests.
*/
@@ -1411,7 +1431,6 @@ ds_device_read (device_t device,
unsigned int *datalen)
{
int avail;
- int mask;
if (device != pseudo_console)
return D_NO_SUCH_DEVICE;
@@ -1425,22 +1444,19 @@ ds_device_read (device_t device,
}
#endif
- mask = sigblock (sigmask (SIGIO));
spin_lock (&readlock);
ioctl (0, FIONREAD, &avail);
if (avail)
{
vm_allocate (mach_task_self (), (pointer_t *)data, bytes_wanted, 1);
*datalen = read (0, *data, bytes_wanted);
- spin_unlock (&readlock);
- sigsetmask (mask);
+ unlock_readlock ();
return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
}
else
{
- spin_unlock (&readlock);
+ unlock_readlock ();
queue_read (DEV_READ, reply_port, reply_type, bytes_wanted);
- sigsetmask (mask);
return MIG_NO_REPLY;
}
}
@@ -1456,7 +1472,6 @@ ds_device_read_inband (device_t device,
unsigned int *datalen)
{
int avail;
- int mask;
if (device != pseudo_console)
return D_NO_SUCH_DEVICE;
@@ -1470,21 +1485,18 @@ ds_device_read_inband (device_t device,
}
#endif
- mask = sigblock (sigmask (SIGIO));
spin_lock (&readlock);
ioctl (0, FIONREAD, &avail);
if (avail)
{
*datalen = read (0, data, bytes_wanted);
- spin_unlock (&readlock);
- sigsetmask (mask);
+ unlock_readlock ();
return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS);
}
else
{
- spin_unlock (&readlock);
+ unlock_readlock ();
queue_read (DEV_READI, reply_port, reply_type, bytes_wanted);
- sigsetmask (mask);
return MIG_NO_REPLY;
}
}
@@ -1691,7 +1703,6 @@ S_io_read (mach_port_t object,
mach_msg_type_number_t amount)
{
mach_msg_type_number_t avail;
- int mask;
if (object != pseudo_console)
return EOPNOTSUPP;
@@ -1705,7 +1716,6 @@ S_io_read (mach_port_t object,
}
#endif
- mask = sigblock (sigmask (SIGIO));
spin_lock (&readlock);
ioctl (0, FIONREAD, &avail);
if (avail)
@@ -1713,15 +1723,13 @@ S_io_read (mach_port_t object,
if (amount > *datalen)
vm_allocate (mach_task_self (), (vm_address_t *) data, amount, 1);
*datalen = read (0, *data, amount);
- spin_unlock (&readlock);
- sigsetmask (mask);
+ unlock_readlock ();
return *datalen == -1 ? errno : 0;
}
else
{
- spin_unlock (&readlock);
+ unlock_readlock ();
queue_read (IO_READ, reply_port, reply_type, amount);
- sigsetmask (mask);
return MIG_NO_REPLY;
}
}