Guard against getting stuck while handling events
authorChris Dickens <christopher.a.dickens@gmail.com>
Sun, 13 Sep 2020 01:39:28 +0000 (18:39 -0700)
committerChris Dickens <christopher.a.dickens@gmail.com>
Sun, 13 Sep 2020 01:39:28 +0000 (18:39 -0700)
commit006ca0fbaa447cac329579d1072304833208358c
treeefe0ff68e3f64c81715ba6dca9a7b2ed1f6b3304
parent89b810ec9bde2689b06fdd2b23ccbb3f926d7575
Guard against getting stuck while handling events

Alba Mendez (user mildsunrise) reports that a thread can get stuck at a
specific point while handling events, thus preventing other events from
being handled. This change addresses two such points in the code:

  1) When processing completed transfers in handle_event_trigger(), the
     function wll loop for as long as the completed_transfers list is
     not empty. Since the event data lock is released and reacquired for
     each completed transfer, it is possible for the completed_transfers
     list to never be emptied. Address this by cutting the list and only
     process the transfers that have completed at that point in time.

  2) When processing events, the Linux backend will reap transfers for
     each device that indicates activity until the reap fails (either
     because there are no completed transfers or some other error
     occurs). It is possible for transfers to be reaped at a rate slower
     than that at which they are completing, thus preventing the loop
     from exiting. Address this by limiting the number of transfers
     reaped for each device to 25 for every call to the Linux backend's
     handle_events() function.

Closes #780

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
libusb/io.c
libusb/libusbi.h
libusb/os/linux_usbfs.c
libusb/version_nano.h