Skip to content

Commit

Permalink
osx: handle report_callback() firing multiple times
Browse files Browse the repository at this point in the history
One invocation of CFRunLoopRunInMode() may fire report_callback()
multiple times. In such a case, the next call to fido_hid_read() may
block for the full duration of the timeout. We can handle this by
querying the (non-blocking) pipe for any readily available data on
entering fido_hid_read() and fall back to executing the run loop if it
was empty.

Debugged with @elibon99 and @martelletto.
  • Loading branch information
LDVG committed Dec 21, 2023
1 parent 99c9b31 commit b2be32b
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/hid_osx.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,11 +552,19 @@ fido_hid_read(void *handle, unsigned char *buf, size_t len, int ms)
return (-1);
}

schedule_io_loop(ctx, ms);

/* check for pending frame */
if ((r = read(ctx->report_pipe[0], buf, len)) == -1) {
fido_log_error(errno, "%s: read", __func__);
return (-1);
if (errno != EAGAIN && errno != EWOULDBLOCK) {
fido_log_error(errno, "%s: read", __func__);
return (-1);
}

schedule_io_loop(ctx, ms);

if ((r = read(ctx->report_pipe[0], buf, len)) == -1) {
fido_log_error(errno, "%s: read", __func__);
return (-1);
}
}

if (r < 0 || (size_t)r != len) {
Expand Down

0 comments on commit b2be32b

Please sign in to comment.