From d50a44ddcd428e992b46d44c4b1404b88fb733a0 Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Fri, 28 Apr 1995 06:59:29 +0000 Subject: [PATCH] In primitive OS2-SELECT-REGISTRY-TEST, there was a window where input could be waiting to be read, but the primitive would be blocked waiting for some input. This was because the primitive is composed of two phases, and input detected in the first phase was not used to prevent blocking in the second. --- v7/src/microcode/pros2io.c | 39 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/v7/src/microcode/pros2io.c b/v7/src/microcode/pros2io.c index 9f9e345d9..a43e84d66 100644 --- a/v7/src/microcode/pros2io.c +++ b/v7/src/microcode/pros2io.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: pros2io.c,v 1.3 1995/01/16 20:58:18 cph Exp $ +$Id: pros2io.c,v 1.4 1995/04/28 06:59:29 cph Exp $ Copyright (c) 1994-95 Massachusetts Institute of Technology @@ -104,6 +104,8 @@ DEFINE_PRIMITIVE ("OS2-SELECT-REGISTRY-TEST", Prim_OS2_select_registry_test, 3, qid_t qid; int n; + /* This first phase checks the qid subqueues and OS2_scheme_tqueue + for any previously-queued input. */ for (qid = 0; (qid <= QID_MAX); qid += 1) { (results [qid]) = 0; @@ -119,34 +121,29 @@ DEFINE_PRIMITIVE ("OS2-SELECT-REGISTRY-TEST", Prim_OS2_select_registry_test, 3, break; } } - while (1) - { - for (qid = 0; (qid <= QID_MAX); qid += 1) - (OS2_scheme_tqueue_avail_map [qid]) = 0; - n = (OS2_tqueue_select (OS2_scheme_tqueue, blockp)); - if (n == (-1)) - break; - else if (n < 0) - { - interruptp = 1; + /* This second phase waits for input if necessary. It does not + check the subqueues for previously-stored data, so it's + important that we already did this. Otherwise we could end up + waiting for input when there was valid input ready. */ + if (blockp) + while (! (inputp || interruptp)) + { + for (qid = 0; (qid <= QID_MAX); qid += 1) + (OS2_scheme_tqueue_avail_map [qid]) = 0; + n = (OS2_tqueue_select (OS2_scheme_tqueue, blockp)); + if (n == (-1)) break; - } - else - { - int breakp = 0; + else if (n < 0) + interruptp = 1; + else for (qid = 0; (qid <= QID_MAX); qid += 1) if (((registry [qid]) != 0) && (OS2_scheme_tqueue_avail_map [qid])) { inputp = 1; (results [qid]) = 1; - if (blockp) - breakp = 1; } - if (breakp) - break; - } - } + } if (inputp) PRIMITIVE_RETURN (LONG_TO_UNSIGNED_FIXNUM (0)); else if (!interruptp) -- 2.25.1