mardi 4 octobre 2016

Libusb hangs when using c++11 async

I'm new to libusb, so I don't really understand it very well. I'm trying to do some USB communication.

I'm using the hotplug feature which works quite well. So I thought when I detect a device arrived event, I would do all communication with USB on another thread using the c++11 async feature, so I could do synchronous I/O with multiple devices to simply codes. Their async I/O is a bit confusing to me. Hopefully I can use the synchronous I/O with c++ async feature.

But I'm having a problem where some libusb call seem to hang when the code is running in c++11 async feature. When it is not running in c++11 async feature it works without any problem.

So I'm assuming it is my c++11 async feature code that's the problem.

Here is my hotplug callback:

int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
  std::future<void> result(std::async([] (libusb_device *d) {

    libusb_device_handle *h;

    printf("%s\n", "Opening");
    int rc = libusb_open(d, &h);
    if(rc != LIBUSB_SUCCESS) {
      printf("ERROR: %s\n", libusb_error_name(rc));
      return;
    }
    printf("%s\n", "Opened");

    printf("%s\n", "Closing");
    libusb_close(h);
    printf("%s\n", "Closed!");

  }, dev));

  result.get();

  return 0;
}

So with this code it hangs on libusb_close

it outputs:

Opening
Opened
Closing

the main code looks like this:

int main(int argc, char* argv[]) {

  int vendor_id = 0x1234;
  int product_id = 0x4556;

  libusb_hotplug_callback_handle *hp = nullptr;
  libusb_context *context = nullptr;
  int rc = libusb_init(&context);

  if(rc < 0)
  {
    return rc;
  }

  libusb_set_debug(context, LIBUSB_LOG_LEVEL_WARNING);

  rc = libusb_hotplug_register_callback(
    context,
    LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
    LIBUSB_HOTPLUG_NO_FLAGS,
    vendor_id,
    product_id,
    LIBUSB_HOTPLUG_MATCH_ANY,
    hotplug_callback,
    NULL,
    hp
    );

  if (LIBUSB_SUCCESS != rc) {
    libusb_exit (context);
    return rc;
  }

  while(1) {
    rc = libusb_handle_events(context);
  }

  return 0;
}

Mind you this code is more prototypal, so it is not really well written, it is still in exploration mode of libusb.

Any help is appreciated.

Aucun commentaire:

Enregistrer un commentaire