I have done some further research into this.  The problem is indeed a 
busy wait loop in the ttol function in gunixio.c see the following 
lines:

824 while (n > 0) {
825   i = write(1,&s[m],n);
826   if (i < 0) {
827     if (errno == EWOULDBLOCK)
828       continue;
829     logerr("ttol write");
830     return(-1);
831   }
........
838 }

If the stdout device is in non-blocking mode then whenver the transmit 
buffer is full the write(1) call will return -1 with errno set to 
EWOULDBLOCK and the continue statement will cause the write call to be 
immediately retried.

>From looking at the ttopen I am not sure if anyone intended stdout to be 
in non-blocking mode but it see stdin and stdout refer to the same 
kernel file table entry, i.e. one was created by a dup(2) of the other 
rather than a second open(2) on "/dev/tty" then setting non-blocking 
mode on stdin would cause stdout to be in non-blocking mode too.

There are an number of possible solutions:

1. One obvious bodge is to insert a usleep(2) call before the continue
   statement.  At broadband speeds anything from 10ms to 100ms doesn't
   appear to slow down the transfer but goes cause the CPU usage to drop
   to below the level of "idle" gnome desktop components.

2. Another possibility would be to set stdout to blocking mode at the
   beginning of the ttol function and set it back to to non-blocking mode
   at the end of the function.

3. A select(2) or poll(2) call could be used to make sure that stdout
   was ready for writing before issuing the write(2) call.

4. The ttopen function could close(2) the existing stdout and open 
   "/dev/tty" afresh to see if we could have stdout permanently in 
   blocking mode.


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to