diff options
author | Michael I. Bushnell <mib@gnu.org> | 1995-11-30 21:01:51 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1995-11-30 21:01:51 +0000 |
commit | 63e7800217bfc228816fd89953664688c9b32c8a (patch) | |
tree | 067ed638bf4efc4647cbbfafa1d739f1d62cce6c /boot | |
parent | c08577c48c1da5b5a6d1443aee9f034651e6eb34 (diff) |
(readlock): New variable.
(read_reply): Check FIONREAD before dequeueing QR so that we don't
abandon requests. Lock READLOCK around FIONREAD/read pair.
(ds_device_read): Lock READLOCK around FIONREAD/read pair.
(ds_device_read_inband): Likewise.
(S_io_read): Likewise.
Diffstat (limited to 'boot')
-rw-r--r-- | boot/boot.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/boot/boot.c b/boot/boot.c index e0f8f80a..31023706 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -60,6 +60,7 @@ mach_port_t pseudo_console; auth_t authserver; spin_lock_t queuelock = SPIN_LOCK_INITIALIZER; +spin_lock_t readlock = SPIN_LOCK_INITIALIZER; mach_port_t php_child_name, psmdp_child_name, taskname; @@ -1009,6 +1010,14 @@ read_reply () char * buf; int amtread; + spin_lock (&readlock); + ioctl (0, FIONREAD, &avail); + if (!avail) + { + spin_unlock (&readlock); + return; + } + spin_lock (&queuelock); if (!qrhead) @@ -1024,16 +1033,14 @@ read_reply () spin_unlock (&queuelock); - ioctl (0, FIONREAD, &avail); - if (!avail) - return; - if (qr->type == DEV_READ) vm_allocate (mach_task_self (), (vm_address_t *)&buf, qr->amount, 1); else buf = alloca (qr->amount); amtread = read (0, buf, qr->amount); + spin_unlock (&readlock); + switch (qr->type) { case DEV_READ: @@ -1410,16 +1417,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); return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS); } else { + spin_unlock (&readlock); queue_read (DEV_READ, reply_port, reply_type, bytes_wanted); sigsetmask (mask); return MIG_NO_REPLY; @@ -1452,15 +1462,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_lock (&readlock); sigsetmask (mask); return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS); } else { + spin_lock (&readlock); queue_read (DEV_READI, reply_port, reply_type, bytes_wanted); sigsetmask (mask); return MIG_NO_REPLY; @@ -1668,17 +1681,20 @@ S_io_read (mach_port_t object, #endif mask = sigblock (sigmask (SIGIO)); + spin_lock (&readlock); ioctl (0, FIONREAD, &avail); if (avail) { if (amount > *datalen) vm_allocate (mach_task_self (), (vm_address_t *) data, amount, 1); *datalen = read (0, *data, amount); + spin_unlock (&readlock); sigsetmask (mask); return *datalen == -1 ? errno : 0; } else { + spin_unlock (&readlock); queue_read (IO_READ, reply_port, reply_type, amount); sigsetmask (mask); return MIG_NO_REPLY; |