[sane-devel] sane_get_devices() is very slow

Henning Meier-Geinitz henning@meier-geinitz.de
Thu, 13 Feb 2003 12:43:51 +0100


Hi,

On Thu, Feb 13, 2003 at 12:54:39AM -0800, Derry Bryson wrote:
> I notice that calling sane_get_devices() is very slow when using the sane dll
> backend.  It takes 36 seconds on my test machine.  This seems way to long just
> to generate a list of scanners to select from.  I haven't looked at it 
> closely, but I would suspect the problem is that each backend is checking
> for a scanner when loaded by the dll backend.  

Most backends check for devices in sane_init. However, the dll backend
runs sane_init of the other backends only when sane_get_devices or
sane_open is called. So if you run sane_open directly, only sane_init
of the specified backend is run.

The most time-consuming part is the USB detection. In SANE 1.0.10
there are several fixes that reduce the amount of time that's needed
to test for USB devices so you should use the latest SANE version.
It shouldn't take more then some seconds now.

If you use the Linux USB kernel scanner driver it also makes sense to
update to the latest driver (http://www.meier-geinitz.de/kernel/). The
latest version doesn't clutter syslog with messages about non-existing
devices. If you don't want to update (and you don't use devfs), you
can at least reduce the number of device nodes in /dev/usb (e.g. keep
only /dev/usb/scanner0 and 1, if you have 2 scanners).

> The TWAIN DSM does basically the same thing, only they specify that the DS 
> (similar to a SANE backend) load and respond as quickly as possible not checking
> to see if the hardware is present. 

Yes, that leads to all kinds of funny results. I don't know if it's by
TWAIN design or just crappy drivers, but TWAIN doesn't reliably work
on my system with more than one driver installed. First, you don't
know which driver is which, because some manufacturers use names like
"USB scanner" or "Scanner 1200" in their TWAIN name. Then you get a
huge list of devices and have to decide which one may be your scanner.
If you click on the wrong one, either nothing happens, or you get an
error message after 1 minute of waiting (something like "TWAIN error
345") or the system freezes. Some drivers don't know about the
scanners they support so they try to drive every scanner that's
connected (and maybe has the same vendor id). "Ratatata", motor moves
in wrong direction. So I'm constantly installing and removing drivers.
Ok, I stop ranting now :-)

> Hopefully I am doing things wrong and someone can point out how I should
> be querying for available devices.  If not, I might propose that SANE be 
> modified such that sane_init() should basically do nothing other than check 
> for basic kernel support (or whatever) and return success and the actual 
> device detection be moved to sane_open()

The SANE standard allows to detect the devices in sane_get_devices and
sane_open. However, that doesn't make any difference at least if the
dll backend is used (see above). And I don't think that you are doing
wrong anything.

> such that sane_get_devices() would return almost instantaneously with
> list of devices supported even if they are not connected. 

Hey, you would get a list of more than 600 devices everytime :-)

> I realize there is a basic difference here in that 
> TWAIN DS's usually only support a single device and SANE backends might
> support a family of devices, but I think it might be better to immediately 
> present the user with a list of devices and let them choose their scanner
> even if it means giving them an error message for non-existant devices.

No, sorry. That's not how it works. It only works for TWAIN because
the user is forced to manually install a driver for every single
scanner and Windows users usally have only one scanner at a single
computer. Think about what would happen if all the scanner drivers had
been provided by Microsoft together with the operating system and
installed by default. If the drivers didn't check for the existance of
the devices, the TWAIN list would be endless.

Bye,
  Henning