@@ -264,16 +264,9 @@ void AsyncPluginImpl::DeviceEvent(HotplugAgent::EventType event,
264264 // Sunlite plugin, if we make the f/w load async we'll need to let the
265265 // factory cancel the load.
266266
267- // Unregister & delete the device in the main thread.
268- if (state->ola_device ) {
269- Future<void > f;
270- m_plugin_adaptor->Execute (
271- NewSingleCallback (this , &AsyncPluginImpl::ShutdownDevice,
272- state->ola_device , &f));
273- f.Get ();
274- state->ola_device = NULL ;
275- }
276- state->DeleteWidget ();
267+ // Unregister & delete the device and widget in the main thread.
268+ m_plugin_adaptor->Execute (
269+ NewSingleCallback (this , &AsyncPluginImpl::ShutdownDeviceState, state));
277270 }
278271}
279272
@@ -353,17 +346,26 @@ bool AsyncPluginImpl::StartAndRegisterDevice(Widget *widget, Device *device) {
353346
354347/*
355348 * @brief Signal widget removal.
356- * @param device_id The device id to remove .
349+ * @param state The DeviceState owning the widget to be removed .
357350 *
358- * This is run within the main thread.
351+ * This must be run within the main thread. The Device destructor below may
352+ * cause libusb_close() to be called, which would deadlock if the hotplug
353+ * event thread were to wait for it, say in AsyncPluginImpl::DeviceEvent().
359354 */
360- void AsyncPluginImpl::ShutdownDevice (Device *device, Future<void > *f) {
361- m_plugin_adaptor->UnregisterDevice (device);
362- device->Stop ();
363- delete device;
364- if (f) {
365- f->Set ();
355+ void AsyncPluginImpl::ShutdownDeviceState (DeviceState *state) {
356+ if (state->ola_device ) {
357+ Device *device = state->ola_device ;
358+ m_plugin_adaptor->UnregisterDevice (device);
359+ device->Stop ();
360+ delete device;
361+ state->ola_device = NULL ;
362+ } else {
363+ /* This case can be legitimate when the widget setup through the
364+ * widget factory is delayed and an unplug event happens before
365+ * that is completed. */
366+ OLA_DEBUG << " ola_device was NULL at shutdown" ;
366367 }
368+ state->DeleteWidget ();
367369}
368370} // namespace usbdmx
369371} // namespace plugin
0 commit comments