fix windows crash when multi-thread do sync transfer
authorFrank Li <Frank.Li@nxp.com>
Fri, 11 Jan 2019 19:09:51 +0000 (13:09 -0600)
committerNathan Hjelm <hjelmn@me.com>
Fri, 5 Apr 2019 04:21:43 +0000 (22:21 -0600)
commitfb864b7cde40695c094363ee97c370ae2acc2e68
tree19221456711e0ea803bd822cbf535574cf716895
parent85d1f361837bd719c433068a8f06d8d5c47d431f
fix windows crash when multi-thread do sync transfer

fun()
{
    libusb_open()
    ... sync transfer
    libusb_close()
}

two thread call fun infininately.

to speed up crash, enable application verifier

below 20 cycle, assert(fd!=NULL) happen at check_pollfds
below 100 cycle, crash at pollable_fd->overlappend in
winusb_get_overlapped result

with this fix, success fun over 1000 cycles

in handle_events

usbi_mutex_lock()
fds = ctx->pollfds
nfds = ctx->pollfds_cnt;
usbi_mutex_unclock()

usbi_poll()
callback.

usbi poll is not in mutex. pollfds may be change by usbi_add_pollfd
and usbi_remove_pollfd.

Although usbi_add_pollfd and usbi_remove_pollfd hold mutex, but
usbi_poll and callback is not in protext of mutex.

windows use fd as index of fb_table. fb_table may changed by
usbi_remove_pollfd.  the map between fd and internal file_descriptor may
be wrong.

this patch added ref count for file_descriptor, only free file_desciptor
and remove it from fb_table when ref count is 0.

ref count will be increase when fds copy with mutex lock.
so fd always index validate file_descriptor.

ref count will be descress before return from handle_events.
the file_descriptor can be free safely at this time.

Closes #521

Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Nathan Hjelm <hjelmn@me.com>
libusb/io.c
libusb/os/poll_posix.h
libusb/os/poll_windows.c
libusb/os/poll_windows.h
libusb/version_nano.h