Paul --
Answers inline below:
> Thank you, Charles. We're always happy to get a bug report with analysis and
> a solution.
>
> A couple of questions:
> 1. This doesn't seem unique to the LINK. Should it be used for all serial
> writes?
I believe so, yes. If any file descriptor is opened with O_NONBLOCK,
then writes are allowed to block and whether or not they do depends on
the implementation (see the man page for the write system call - on
linux EWOULDBLOCK == EAGAIN). Admittedly, it's not common to see a
write block when writing to a traditional serial port.
> 2. Why would the write block?
I'm not sure. I think in my case it's because I'm talking to the
serial device via an older 1.1 usb bus and the keyspan serial device.
Perhaps, if the usb controller is busy doing something else, then when
the write request comes in, it need to be either buffered or delayed.
Since the port is in non-canonical mode, my guess is that it's not
allowed to buffer and since it's in O_NONBLOCK mode, it's not allowed
to delay. Thus, it returns saying it wanted to block, but didn't.
I admit I didn't really look very deeply into the "why did the write
block" aspect due to (1) above.
>
> About the specific code:
> Is there a guaranteed exit to the loop?
As written, no. Some sort of max retry count would be useful to make
sure it doesn't become an infinite loop. In my case I wanted to see
how big the numbers got to see what a reasonable maximum would be. In
general I never saw any numbers above two retires.
Potentially a max retry count could be added to the timeout struct.
Assuming one wanted to keep a 5 second timeout for writes, then the
1ms pause (usleep(1000)) means a retry count of 5000.
Alternatively, I saw some code for handling timeouts, but I didn't
look at the code close enough to see if that was being set for both
reads and writes.
If there is concern about the portability of usleep(), another
alternative would be to use sleep(0). A sleep(0) call is basically a
voluntary yield to the OS allowing other things to run which would
provide a similar effect to the usleep - a short delay to let the
reason for the write block to go away.
> Also do we need the pause for non EWOULDBLOCK errors?
I don't think so, but it would do no harm. The point to the delay in
response to EWOULDBLOCK is to let other things happen in the hope the
next attempt will work.
If you would like me to enhance this patch to include writes to other
devices and a max retry count, please let me know.
>
> Paul Alfille
>
> On Sun, Jul 27, 2008 at 3:53 PM, Charles Spirakis <[EMAIL PROTECTED]> wrote:
>
>> + do {
>> + LEVEL_DEBUG("erc: %d\n",
>> ewouldblock_retry_count++);
>> + // Not all versions of gcc/linux touch the
>> + // errno on success, so make sure there is no
>> + // garbage left in errno from a previous access
>> + errno = 0;
>> + write_or_error =
>> write(pn->selected_connection->file_descriptor, buf,
>>
>> left_to_write);
>> - Debug_Bytes("Link write", buf, left_to_write);
>> - //printf("Link write = %d\n",(int)write_or_error);
>> + Debug_Bytes("Link write", buf, left_to_write);
>> + //printf("Link woe = %d\n",(int)write_or_error);
>> + if ((write_or_error < 0) && (EWOULDBLOCK == errno))
>> {
>> + usleep(1000);
>> + }
>> + } while (EWOULDBLOCK == errno);
>>
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Owfs-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/owfs-developers