Exemplo n.º 1
0
int freespace_getNextTimeout(int* timeoutMsOut) {
    struct timeval tv;
    int hotplugTimeout = freespace_hotplug_timeout();
    int timeoutMs;

    int rc = libusb_get_next_timeout(freespace_libusb_context, &tv);
    if (rc == 1) {
        // libusb has a timeout
        timeoutMs = tv.tv_sec * 1000 + tv.tv_usec / 1000;

        if (hotplugTimeout > 0 && hotplugTimeout < timeoutMs) {
            timeoutMs = hotplugTimeout;
        }
    } else if (rc == 0 && hotplugTimeout > 0) {
        // The hotplug code has a timeout.
        timeoutMs = hotplugTimeout;
    } else {
        // No one has a timeout.
        timeoutMs = -1;
    }
    *timeoutMsOut = timeoutMs;
    return libusb_to_freespace_error(rc);
}
Exemplo n.º 2
0
/** USB event source prepare() method.
 */
static gboolean usb_source_prepare(GSource *source, int *timeout)
{
	int64_t now_us, usb_due_us;
	struct usb_source *usource;
	struct timeval usb_timeout;
	int remaining_ms;
	int ret;

	usource = (struct usb_source *)source;

	ret = libusb_get_next_timeout(usource->usb_ctx, &usb_timeout);
	if (G_UNLIKELY(ret < 0)) {
		sr_err("Failed to get libusb timeout: %s",
			libusb_error_name(ret));
	}
	now_us = g_source_get_time(source);

	if (usource->due_us == 0) {
		/* First-time initialization of the expiration time */
		usource->due_us = now_us + usource->timeout_us;
	}
	if (ret == 1) {
		usb_due_us = (int64_t)usb_timeout.tv_sec * G_USEC_PER_SEC
				+ usb_timeout.tv_usec + now_us;
		if (usb_due_us < usource->due_us)
			usource->due_us = usb_due_us;
	}
	if (usource->due_us != INT64_MAX)
		remaining_ms = (MAX(0, usource->due_us - now_us) + 999) / 1000;
	else
		remaining_ms = -1;

	*timeout = remaining_ms;

	return (remaining_ms == 0);
}
Exemplo n.º 3
0
int hmcfgusb_poll(struct hmcfgusb_dev *dev, int timeout)
{
	struct timeval tv;
	int usb_event = 0;
	int timed_out = 0;
	int i;
	int n;
	int fd_n;
	int err;

	errno = 0;

	memset(&tv, 0, sizeof(tv));
	err = libusb_get_next_timeout(NULL, &tv);
	if (err < 0) {
		fprintf(stderr, "libusb_get_next_timeout: %s\n", usb_strerror(err));
		errno = EIO;
		return -1;
	} else if (err == 0) {
		/* No pending timeout or a sane platform */
	} else {
		if ((tv.tv_sec == 0) && (tv.tv_usec == 0)) {
			usb_event = 1;
		} else if ((tv.tv_sec * 1000) < timeout) {
			timeout = tv.tv_sec * 1000;
		}
	}

	if (!usb_event) {
		for (i = 0; i < dev->n_pfd; i++) {
			dev->pfd[i].revents = 0;
		}

		n = poll(dev->pfd, dev->n_pfd, timeout);
		if (n < 0) {
			perror("poll");
			errno = 0;
			return -1;
		} else if (n == 0) {
			usb_event = 1;
			timed_out = 1;
		} else {
			for (fd_n = 0; fd_n < dev->n_pfd; fd_n++) {
				if (dev->pfd[fd_n].revents) {
					if (fd_n < dev->n_usb_pfd) {
						usb_event = 1;
						break;
					} else {
						errno = 0;
						return dev->pfd[fd_n].fd;
					}
				}
			}
		}
	}

	if (usb_event) {
		memset(&tv, 0, sizeof(tv));
		err = libusb_handle_events_timeout_completed(NULL, &tv, NULL);
		if (err < 0) {
			fprintf(stderr, "libusb_handle_events_timeout_completed: %s\n", usb_strerror(err));
			errno = EIO;
			return -1;
		}
	}

	errno = 0;
	if (quit) {
		fprintf(stderr, "closing device-connection due to error %d\n", quit);
		errno = quit;
	}

	if (timed_out)
		errno = ETIMEDOUT;

	return -1;
}
Exemplo n.º 4
0
void
USBLoop::Run (pth_sem_t * stop1)
{
  fd_set r, w, e;
  int rc, fds, i;
  struct timeval tv, tv1;
  const struct libusb_pollfd **usbfd, **usbfd_orig;
  pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1);
  // The next two are dummy allocations which will be replaced later
  pth_event_t event = pth_event (PTH_EVENT_SEM, stop1);
  pth_event_t timeout = pth_event (PTH_EVENT_SEM, stop1);

  tv1.tv_sec = tv1.tv_usec = 0;
  TRACEPRINTF (t, 10, this, "LoopStart");
  while (pth_event_status (stop) != PTH_STATUS_OCCURRED)
    {
      TRACEPRINTF (t, 10, this, "LoopBegin");
      FD_ZERO (&r);
      FD_ZERO (&w);
      FD_ZERO (&e);
      fds = 0;
      rc = 0;

      usbfd = libusb_get_pollfds (context);
      usbfd_orig = usbfd;
      if (usbfd)
	while (*usbfd)
	  {
	    if ((*usbfd)->fd > fds)
	      fds = (*usbfd)->fd;
	    if ((*usbfd)->events & POLLIN)
	      FD_SET ((*usbfd)->fd, &r);
	    if ((*usbfd)->events & POLLOUT)
	      FD_SET ((*usbfd)->fd, &w);
	    usbfd++;
	  }
      free (usbfd_orig);

      i = libusb_get_next_timeout (context, &tv);
      if (i < 0)
	break;
      if (i > 0)
	{
	  pth_event (PTH_EVENT_RTIME | PTH_MODE_REUSE,
		     timeout, pth_time (tv.tv_sec, tv.tv_usec));
	  pth_event_concat (stop, timeout, NULL);
	}
      pth_event (PTH_EVENT_SELECT | PTH_MODE_REUSE, event, &rc, fds + 1, &r,
		 &w, &e);
      pth_event_concat (stop, event, NULL);
      TRACEPRINTF (t, 10, this, "LoopWait");
      pth_wait (stop);
      TRACEPRINTF (t, 10, this, "LoopProcess");

      pth_event_isolate (event);
      pth_event_isolate (timeout);

      if (libusb_handle_events_timeout (context, &tv1))
	break;
      TRACEPRINTF (t, 10, this, "LoopEnd");
    }
  TRACEPRINTF (t, 10, this, "LoopStop");

  pth_event_free (timeout, PTH_FREE_THIS);
  pth_event_free (event, PTH_FREE_THIS);
  pth_event_free (stop, PTH_FREE_THIS);
}
Exemplo n.º 5
0
static void run_main_loop(void)
{
    const struct libusb_pollfd **pollfds = NULL;
    fd_set readfds, writefds;
    int i, n, nfds;
    struct timeval timeout, *timeout_p;

    while (running && client_fd != -1) {
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);

        FD_SET(client_fd, &readfds);
        if (usbredirhost_has_data_to_write(host)) {
            FD_SET(client_fd, &writefds);
        }
        nfds = client_fd + 1;

        free(pollfds);
        pollfds = libusb_get_pollfds(ctx);
        for (i = 0; pollfds && pollfds[i]; i++) {
            if (pollfds[i]->events & POLLIN) {
                FD_SET(pollfds[i]->fd, &readfds);
            }
            if (pollfds[i]->events & POLLOUT) {
                FD_SET(pollfds[i]->fd, &writefds);
            }
            if (pollfds[i]->fd >= nfds)
                nfds = pollfds[i]->fd + 1;
        }

        if (libusb_get_next_timeout(ctx, &timeout) == 1) {
            timeout_p = &timeout;
        } else {
            timeout_p = NULL;
        }
        n = select(nfds, &readfds, &writefds, NULL, timeout_p);
        if (n == -1) {
            if (errno == EINTR) {
                continue;
            }
            perror("select");
            break;
        }
        memset(&timeout, 0, sizeof(timeout));
        if (n == 0) {
            libusb_handle_events_timeout(ctx, &timeout);
            continue;
        }

        if (FD_ISSET(client_fd, &readfds)) {
            if (usbredirhost_read_guest_data(host)) {
                break;
            }
        }
        /* usbredirhost_read_guest_data may have detected client disconnect */
        if (client_fd == -1)
            break;

        if (FD_ISSET(client_fd, &writefds)) {
            if (usbredirhost_write_guest_data(host)) {
                break;
            }
        }

        for (i = 0; pollfds && pollfds[i]; i++) {
            if (FD_ISSET(pollfds[i]->fd, &readfds) ||
                FD_ISSET(pollfds[i]->fd, &writefds)) {
                libusb_handle_events_timeout(ctx, &timeout);
                break;
            }
        }
    }
    if (client_fd != -1) { /* Broken out of the loop because of an error ? */
        close(client_fd);
        client_fd = -1;
    }
    free(pollfds);
}
Exemplo n.º 6
0
static int process_events_once(int timeout)
{
	struct timeval tv = {0, 0};
	int r;
	int libusb_delay;
	int delay;
	unsigned int i;
	char process_libusb = 0;

	r = libusb_get_next_timeout(ctx, &tv);
	if (r == 1 && tv.tv_sec == 0 && tv.tv_usec == 0)
	{
		r = libusb_handle_events_timeout(ctx, &tv);
	}

	delay = libusb_delay = tv.tv_sec * 1000 + tv.tv_usec;
	if (delay <= 0 || delay > timeout)
	{
		delay = timeout;
	}

	CHECK_NEGATIVE(poll(fds, nfds, delay));

	process_libusb = (r == 0 && delay == libusb_delay);

	for (i = 0; i < nfds; ++i)
	{
		if (fds[i].fd == tap_fd) {
			if (fds[i].revents)
			{
				CHECK_NEGATIVE(read_tap());
			}
			continue;
		}
		process_libusb |= fds[i].revents;
	}

	if (process_libusb)
	{
		struct timeval tv = {.tv_sec = 0, .tv_usec = 0};
		CHECK_NEGATIVE(libusb_handle_events_timeout(ctx, &tv));
	}

	return 0;
}

/* handle events until timeout is reached or all of the events in event_mask happen */
static int process_events_by_mask(int timeout, unsigned int event_mask)
{
	struct timeval start, curr;
	int r;
	int delay = timeout;

	CHECK_NEGATIVE(gettimeofday(&start, NULL));

	wd_status.info_updated &= ~event_mask;

	while ((event_mask == 0 || (wd_status.info_updated & event_mask) != event_mask) && delay >= 0) {
		long a;

		CHECK_NEGATIVE(process_events_once(delay));

		if (device_disconnected) {
			exit_release_resources(0);
		}

		CHECK_NEGATIVE(gettimeofday(&curr, NULL));

		a = (curr.tv_sec - start.tv_sec) * 1000 + (curr.tv_usec - start.tv_usec) / 1000;
		delay = timeout - a;
	}

	wd_status.info_updated &= ~event_mask;

	return (delay > 0) ? delay : 0;
}

int alloc_fds()
{
	int i;
	const struct libusb_pollfd **usb_fds = libusb_get_pollfds(ctx);

	if (!usb_fds)
	{
		return -1;
	}

	nfds = 0;
	while (usb_fds[nfds])
	{
		nfds++;
	}
	if (tap_fd != -1) {
		nfds++;
	}

	if(fds != NULL) {
		free(fds);
	}

	fds = (struct pollfd*)calloc(nfds, sizeof(struct pollfd));
	for (i = 0; usb_fds[i]; ++i)
	{
		fds[i].fd = usb_fds[i]->fd;
		fds[i].events = usb_fds[i]->events;
		set_coe(usb_fds[i]->fd);
	}
	if (tap_fd != -1) {
		fds[i].fd = tap_fd;
		fds[i].events = POLLIN;
		fds[i].revents = 0;
	}

	free(usb_fds);

	return 0;
}