Пример #1
0
int
obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
    int num_ready)
{
	struct libusb_device_handle *handle;
	struct handle_priv *hpriv = NULL;
	struct usbi_transfer *itransfer;
	struct pollfd *pollfd;
	int i, err = 0;

	usbi_dbg("");

	pthread_mutex_lock(&ctx->open_devs_lock);
	for (i = 0; i < nfds && num_ready > 0; i++) {
		pollfd = &fds[i];

		if (!pollfd->revents)
			continue;

		hpriv = NULL;
		num_ready--;
		list_for_each_entry(handle, &ctx->open_devs, list,
		    struct libusb_device_handle) {
			hpriv = (struct handle_priv *)handle->os_priv;

			if (hpriv->pipe[0] == pollfd->fd)
				break;

			hpriv = NULL;
		}

		if (NULL == hpriv) {
			usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
			err = ENOENT;
			break;
		}

		if (pollfd->revents & POLLERR) {
			usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
			usbi_handle_disconnect(handle);
			continue;
		}

		if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
			err = errno;
			break;
		}

		if ((err = usbi_handle_transfer_completion(itransfer,
		    LIBUSB_TRANSFER_COMPLETED)))
			break;
	}
	pthread_mutex_unlock(&ctx->open_devs_lock);

	if (err)
		return _errno_to_libusb(err);

	return (LIBUSB_SUCCESS);
}
Пример #2
0
static int wince_handle_events(
	struct libusb_context *ctx,
	struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
	struct wince_transfer_priv* transfer_priv = NULL;
	POLL_NFDS_TYPE i = 0;
	BOOL found = FALSE;
	struct usbi_transfer *transfer;
	DWORD io_size, io_result;
	int r = LIBUSB_SUCCESS;

	usbi_mutex_lock(&ctx->open_devs_lock);
	for (i = 0; i < nfds && num_ready > 0; i++) {

		usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);

		if (!fds[i].revents)
			continue;

		num_ready--;

		// Because a Windows OVERLAPPED is used for poll emulation,
		// a pollable fd is created and stored with each transfer
		usbi_mutex_lock(&ctx->flying_transfers_lock);
		list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
			transfer_priv = usbi_transfer_get_os_priv(transfer);
			if (transfer_priv->pollable_fd.fd == fds[i].fd) {
				found = TRUE;
				break;
			}
		}
		usbi_mutex_unlock(&ctx->flying_transfers_lock);

		if (found && HasOverlappedIoCompleted(transfer_priv->pollable_fd.overlapped)) {
			io_result = (DWORD)transfer_priv->pollable_fd.overlapped->Internal;
			io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
			usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
			// let handle_callback free the event using the transfer wfd
			// If you don't use the transfer wfd, you run a risk of trying to free a
			// newly allocated wfd that took the place of the one from the transfer.
			wince_handle_callback(transfer, io_result, io_size);
		} else if (found) {
			usbi_err(ctx, "matching transfer for fd %d has not completed", fds[i]);
			r = LIBUSB_ERROR_OTHER;
			break;
		} else {
			usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
			r = LIBUSB_ERROR_NOT_FOUND;
			break;
		}
	}
	usbi_mutex_unlock(&ctx->open_devs_lock);

	return r;
}
Пример #3
0
static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
{
	struct windows_context_priv *priv = _context_priv(ctx);
	struct usbi_transfer *itransfer;
	DWORD io_size, io_result;
	POLL_NFDS_TYPE i;
	bool found;
	int transfer_fd;
	int r = LIBUSB_SUCCESS;

	usbi_mutex_lock(&ctx->open_devs_lock);
	for (i = 0; i < nfds && num_ready > 0; i++) {

		usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);

		if (!fds[i].revents)
			continue;

		num_ready--;

		// Because a Windows OVERLAPPED is used for poll emulation,
		// a pollable fd is created and stored with each transfer
		found = false;
		transfer_fd = -1;
		usbi_mutex_lock(&ctx->flying_transfers_lock);
		list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) {
			transfer_fd = priv->backend->get_transfer_fd(itransfer);
			if (transfer_fd == fds[i].fd) {
				found = true;
				break;
			}
		}
		usbi_mutex_unlock(&ctx->flying_transfers_lock);

		if (found) {
			priv->backend->get_overlapped_result(itransfer, &io_result, &io_size);

			usbi_remove_pollfd(ctx, transfer_fd);

			// let handle_callback free the event using the transfer wfd
			// If you don't use the transfer wfd, you run a risk of trying to free a
			// newly allocated wfd that took the place of the one from the transfer.
			windows_handle_callback(priv->backend, itransfer, io_result, io_size);
		} else {
			usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i].fd);
			r = LIBUSB_ERROR_NOT_FOUND;
			break;
		}
	}
	usbi_mutex_unlock(&ctx->open_devs_lock);

	return r;
}
Пример #4
0
void
obsd_close(struct libusb_device_handle *handle)
{
	struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
	struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;

	usbi_dbg("close: fd %d", dpriv->fd);

	close(dpriv->fd);
	dpriv->fd = -1;

	usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);

	close(hpriv->pipe[0]);
	close(hpriv->pipe[1]);
}