![]() |
#1 |
Guru
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 735
Karma: 35936
Join Date: Apr 2011
Location: Shrewsury, MA
Device: Lenovo Android Tablet
|
Cannot 'eject' Kindle?
When I sync from Calibre to Kindle via USB, I sometimes later eject it (windows 7) to allow it to charge. If I then try to sync my Nexus 7 using Calibre Companion, it fails saying Calibre is already connected to another device. I have to pull the USB completely to overcome this.
Is there a Calibre setting I've missed that would solve this, or...? |
![]() |
![]() |
![]() |
#2 |
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,345
Karma: 27182818
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
Eject it using calibre instead, right click the device icon on the calibre toolbar.
|
![]() |
![]() |
Advert | |
|
![]() |
#3 |
Guru
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 735
Karma: 35936
Join Date: Apr 2011
Location: Shrewsury, MA
Device: Lenovo Android Tablet
|
|
![]() |
![]() |
![]() |
#4 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,443
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
@kovid: after a wireless device opens a socket, the wireless device driver waits for up to 6 seconds to be polled to open a connection. Is it reasonable that this isn't long enough? Device.py runs the loop every 2 seconds. I don't know how long the scan takes, but it is clearly less that 4 seconds if nothing is plugged in.
What I am worried about is if for some reason the previous device is not in "ejected_devices" then all sorts of processing might happen trying to open the previously ejected device. I see timeouts of 5 seconds and 7 seconds in the device subsystem in usbms. Perhaps this problem could go away if the wireless device driver were at the top of the device scan list? It responds very quickly whether or not a device is waiting to connect. |
![]() |
![]() |
![]() |
#5 |
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,345
Karma: 27182818
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
IIRC when you eject a USB device from within calibre, it remains in ejected_devices until the USB scan no longer detects the device, at which point it is removed from ejected_devices.
A connection attempt to an ejected device will only happen if the system at some point reports that device as no longer present and then later reports it as present again. I dont think anything can be done about that, since it indicates something buggy in the system in question. Doesn't the wireless driver listen for connections in a separate thread? In which case why would re-ordering the scan list make any difference? |
![]() |
![]() |
Advert | |
|
![]() |
#6 | |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,443
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
The order that devices are processed in device.DeviceManager.do_connect appears to be the order of the plugins in customize.ui.py. If I am reading this correctly, if a device that is "misbehaving" in terms of eject status (or some other reason) appears before some other device in the possibly_connected list then the misbehaving device will always be processed first. My thought is that if the wireless driver were higher in the list then it would be polled before the misbehaving device. This change is safe because there isn't any ambiguity about whether the wireless driver is connected or ejected. Ejecting closes the socket. There is no cable that must be removed. The other option might be to redo the wireless driver with MANAGES_DEVICE_PRESENCE == True. That would move it into the other loop along with the MTP driver. I don't know what a change like this would entail. |
|
![]() |
![]() |
![]() |
#7 |
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,345
Karma: 27182818
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
My point was that since the socket connection is accepted asynchronously, it would still be possible for a misbehaving device to block it, since, the connection could be accepted just before the misbehaving device is polled on the separate device thread, regardless of the order of devices in possibly_connected.
Without looking at the wireless driver code, I'm guessing that the reason it waits for a fixed time, is that it doesn't know if there is a currently connected device in the device thread? My inclination would be to add some API to the device driver interface so that the device thread can notify any drivers that it is already connected and therefore, they should abort any connection attempts. Then the connection thread can simply wait forever, until either the device subsytem informs it that it is connected, or actually tries to connect. |
![]() |
![]() |
![]() |
#8 | ||
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,443
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
Quote:
To be sure I understand: you are suggesting that device.py (somehow) notify *all* device drivers when *any* device connects and disconnects. Given this notification, when the wireless device driver sub-thread accepts a connection, it checks the "already connected" state and waves off the connecting device if true. It would continue to check this state periodically and notify the connecting device if the state changes, with no limit on the number of checks. Of course it would do the right thing if the connecting device is itself. The new API would look something like def device_connected(self, device) and def device_disconnected(self, device) The above is straightforward to implement. I will give it a try. |
||
![]() |
![]() |
![]() |
#9 |
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,345
Karma: 27182818
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
An alternate, probably, more performant implementation would be to use a global object named connected_device declared in devices.interface:
_connected_device = None def connected_device(): return _connected_device def set_connected_device(dev=None): global _connected_device _connected_device = dev The GUI can simply call set_connected_device on ever device connection/disconnection. Drivers that are interested in connected status can call connected_device() That avoids the overhead of calling a function on every device driver. |
![]() |
![]() |
![]() |
#10 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,443
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
I pushed the changes.
I ended up making a class instance instead of using two global functions, in order to reduce pollution of the namespace when importing. I am also depending on the GIL to ensure that the assignment of the device to the class variable is atomic. |
![]() |
![]() |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
If I can't eject my Kindle, what does it mean? (Also, new books not showing up) | HelenaJole | Amazon Kindle | 12 | 10-12-2010 12:04 AM |
eject device ( kindle 3 - Win 7 - 64) | cybmole | Calibre | 1 | 09-29-2010 08:06 AM |
Can't Eject Kindle | Sydney's Mom | Calibre | 2 | 02-03-2010 06:03 PM |
eject kindle in linux (not unmount) | demoric | Amazon Kindle | 4 | 08-02-2009 05:33 PM |
Message to Eject Kindle From PC If I Want To Use It | glorya | Amazon Kindle | 20 | 04-24-2009 01:06 PM |