David Brownell wrote:
> 
> On Thursday 19 August 2004 8:32 am, Alan Stern wrote:
> > On Thu, 19 Aug 2004, Alexander N. Kozhushkin wrote:
> >
> > > 3. The  call  completes without  waiting  for  the  device.  The  file
> > >    descriptor has been unusable for I/O operations on the device since
> > >    the disconnection, therefore the result of the call is not affected
> > >    if the  device has  been connected again.   The result of  the call
> > >    depends on  the kind of  the called function and  other conditions.
> > >    However, the 'close' function closes the file, and there are system
> > >    calls which produce a specific error code in such situations.
> >
> > As I understand it, the kernel should always use your option 3.
> 
> Certainly USB should do it that way in 2.6, although the device
> drivers can try to implement other behavior.  I think that's made
> a big improvement in robustness.
> 
> Other hotpluggable busses (or 2.4) may not act quite the same.
> 
> - Dave
> 
> The standard behavior should be: read, write, ioctl, fcntl, open,... 
> return ENODEV or something similar.  Close should return 0.
>
> Alan Stern

Hi,

Well, and what about the 'select()' system call?

   It is not a good idea  to make the 'select()' function fail if some
file  descriptor in  the  argument descriptor  sets  corresponds to  a
disconnected  device.  It is  much better  if the  'select()' function
treats  such   a  file   descriptor  as  if   it  is  ready   for  I/O
operations. Such a 'select()' function is more convenient in practice.

   Consider two  'select()' functions.  The first function  fails with
the  'ENODEV' error  code  if  some file  descriptor  in the  argument
descriptor  sets corresponds  to  a disconnected  device.  The  second
treats such  a file  descriptor as if  it is  valid and ready  for the
respective  I/O operation.  That is,  if some  element of  an argument
descriptor set corresponds to a disconnected device, then the function
adds that file descriptor to  the respective output descriptor set and
returns successfully. In this case,  the output of the second function
contains not only  the elements of the argument  descriptor sets which
are really ready for reading or writing or really have exceptions, but
also the elements  of those sets which correspond  to the disconnected
device.

   First,  if  a call  to  'select()'  completed  successfully, it  is
possible  that the  device which  corresponds to  some element  of the
output  descriptor   sets  has   been  disconnected  since   the  call
completion. So it is always  possible that some file descriptor in the
output descriptor sets is unusable for I/O operations. Therefore, if a
call  to  either  of  the  'select()' functions  above  has  completed
successfully and has modified  the argument descriptor sets, then each
file descriptor  in the modified  descriptor sets is either  ready for
the respective I/O  operation or unusable.  So the  results of all I/O
calls making use of the 'select()' results are still to be checked for
the 'ENODEV' error.

   Second, if a call to  the first 'select()' function has failed with
the 'ENODEV'  error code,  the application is  able to see  that there
exists a device which was disconnected.  However, ordinarily there are
several elements in the argument descriptor sets. So the result of the
call does  not provide the  application with any  reliable information
about  which file  descriptors in  the argument  descriptor  sets were
spoiled  by  the  disconnection.   The  information  returned  by  the
function in this  case is incomplete, and additional  system calls are
needed only to find those  spoiled file descriptors among the elements
of the argument descriptor sets.
   On the other hand, if some device was disconnected before a call to
the second  'select()' function, and  in the argument  descriptor sets
there are file descriptors which correspond to that device, then those
file  descriptors are  in the  respective output  descriptor  sets. It
should be noted  that a 'select()' call is  normally followed by calls
to  functions which  perform read  and  write operations  on the  file
descriptors in  the output  descriptor sets, i.e.,  on the  ready file
descriptors. As  noted before,  the results of  those calls are  to be
checked  for the  'ENODEV' error.  So, in  this case,  the information
provided by  the second 'select()' function is  usually sufficient not
only to  determine that  there is a  disconnected device, but  also to
find the unusable file descriptors in the argument descriptor sets and
to  distinguish between  them and  the  other elements  of the  output
descriptor sets which are actually ready for reading or writing.

   Moreover, if the second 'select()'  function is in use, it does not
matter whether a  file descriptor in the argument  descriptor sets was
spoiled before  a 'select()' call or  a file descriptor  in the output
descriptor sets was  spoiled immediately after it. In  either case the
device disconnection  which spoiled the file descriptor  is handled in
the  same way.   Instead of  checking the  'select()' results  for the
'ENODEV' error and doing excessive  system calls only to find unusable
file descriptors,  the application performs the calls  to 'read()' and
'write()' on the file  descriptors in the respective output descriptor
set and checks the results of  those read and write operations for the
'ENODEV' error,  as usually.  Those  'read()' and 'write()'  calls are
used  to  perform  I/O  operations  and  to  find  the  unusable  file
descriptors at the same time.

   Therefore, the  results of the second 'select()'  function are more
suitable in  practice than  the results  of the first  one, and  so it
seems that the  following behavior of the 'select()'  function is more
reasonable:
If a device was disconnected  after a file descriptor corresponding to
the device was  created, that file descriptor is  assumed to be always
ready for  reading and writing; the  disconnection is assumed  to be a
permanent exceptional condition on the file descriptor. The 'select()'
function treats that  file descriptor as a valid and  ready one. So if
the file descriptor  is contained in a descriptor  set supplied to the
'select()' function as an  argument, then the 'select()' function adds
the  file  descriptor to  the  respective  output  descriptor set  and
returns successfully.  In such a situation, the normal return value is
clearly greater than 0, instead of "-1".


Sincerely yours,
                A.N. Kozhushkin.



-- 
*********************************************************
                Alexander N. Kozhushkin.
            ADDR: [EMAIL PROTECTED]
*********************************************************


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM. 
Deadline: Sept. 13. Go here: http://sf.net/ppc_contest.php
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to