[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fix latent bug in process.c

From: Tom Tromey
Subject: fix latent bug in process.c
Date: Mon, 13 Aug 2012 13:25:43 -0600

While looking into making process.c thread-friendly, I found an oddity
in process.c.  It looks like a latent bug to me, but I was hoping that
somebody more familiar with the code could take a look.

The appended patch shows the issue.

First, we unconditionally set Writeok, even if SELECT_CANT_DO_WRITE_MASK
is set.  It seems to me that in one branch we ought to clear Writeok;
and only set it in the other.

Second, and more importantly, in the loop after the select completes, we
check if an fd is in write_mask.  But, I think this will always be true
for any fd for which add_write_fd has been called -- meaning that the
callback will be called even if the fd is not in fact available for

The fix here is to check Writeok rather than write_mask (and this is
what necessitated the first change -- to ensure Writeok is always set



    fix latent bug in process.c
        * process.c (wait_reading_process_output): Handle Writeok
        depending on SELECT_CANT_DO_WRITE_MASK.  Check Writeok bits,
        not write_mask.

diff --git a/src/process.c b/src/process.c
index 0be624a..278d143 100644
--- a/src/process.c
+++ b/src/process.c
@@ -4522,11 +4522,12 @@ wait_reading_process_output (intmax_t time_limit, int 
nsecs, int read_kbd,
            Available = non_keyboard_wait_mask;
            Available = input_wait_mask;
-          Writeok = write_mask;
           check_write = 0;
+         FD_ZERO (&Writeok);
           check_write = 1;
+          Writeok = write_mask;
          check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
@@ -4792,7 +4793,7 @@ wait_reading_process_output (intmax_t time_limit, int 
nsecs, int read_kbd,
               && d->func != 0
               && (d->condition & FOR_READ) != 0)
             d->func (channel, d->data, 1);
-          if (FD_ISSET (channel, &write_mask)
+          if (FD_ISSET (channel, &Writeok)
               && d->func != 0
               && (d->condition & FOR_WRITE) != 0)
             d->func (channel, d->data, 0);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]