linux: rework hotplug lock handling
authorHans de Goede <hdegoede@redhat.com>
Fri, 24 May 2013 12:40:27 +0000 (14:40 +0200)
committerHans de Goede <hdegoede@redhat.com>
Thu, 30 May 2013 12:20:26 +0000 (14:20 +0200)
I could not find if libudev is completely threadsafe anywhere, so rework
the lock handling to serialize all libudev accesses. This is a preparation
patch for adding hotplug_poll support, see the next patch in this series.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
libusb/os/linux_netlink.c
libusb/os/linux_udev.c
libusb/os/linux_usbfs.c
libusb/os/linux_usbfs.h
libusb/version_nano.h

index 17eb944..7b1fdcd 100644 (file)
@@ -234,7 +234,9 @@ static void *linux_netlink_event_thread_main(void *arg)
                        break;
                }
 
+               usbi_mutex_static_lock(&linux_hotplug_lock);
                linux_netlink_read_message();
+               usbi_mutex_static_unlock(&linux_hotplug_lock);
        }
 
        return NULL;
index 9045c2e..cf5f08c 100644 (file)
@@ -135,7 +135,9 @@ static void *linux_udev_event_thread_main(void *arg)
                        break;
                }
 
+               usbi_mutex_static_lock(&linux_hotplug_lock);
                udev_hotplug_event();
+               usbi_mutex_static_unlock(&linux_hotplug_lock);
        }
 
        usbi_dbg("udev event thread exiting");
index 57ab80c..f86d37a 100644 (file)
@@ -120,8 +120,8 @@ static int sysfs_has_descriptors = -1;
 /* how many times have we initted (and not exited) ? */
 static volatile int init_count = 0;
 
-/* Protects init_count and serializes scan_devices versus the hotplug-thread */
-static usbi_mutex_static_t hotplug_lock = USBI_MUTEX_INITIALIZER;
+/* Serialize hotplug start/stop, scan-devices, event-thread, and poll */
+usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER;
 
 static int linux_start_event_monitor(void);
 static int linux_stop_event_monitor(void);
@@ -418,7 +418,7 @@ static int op_init(struct libusb_context *ctx)
        if (sysfs_has_descriptors)
                usbi_dbg("sysfs has complete descriptors");
 
-       usbi_mutex_static_lock(&hotplug_lock);
+       usbi_mutex_static_lock(&linux_hotplug_lock);
        r = LIBUSB_SUCCESS;
        if (init_count == 0) {
                /* start up hotplug event handler */
@@ -432,20 +432,20 @@ static int op_init(struct libusb_context *ctx)
                        linux_stop_event_monitor();
        } else
                usbi_err(ctx, "error starting hotplug event monitor");
-       usbi_mutex_static_unlock(&hotplug_lock);
+       usbi_mutex_static_unlock(&linux_hotplug_lock);
 
        return r;
 }
 
 static void op_exit(void)
 {
-       usbi_mutex_static_lock(&hotplug_lock);
+       usbi_mutex_static_lock(&linux_hotplug_lock);
        assert(init_count != 0);
        if (!--init_count) {
                /* tear down event handler */
                (void)linux_stop_event_monitor();
        }
-       usbi_mutex_static_unlock(&hotplug_lock);
+       usbi_mutex_static_unlock(&linux_hotplug_lock);
 }
 
 static int linux_start_event_monitor(void)
@@ -1056,11 +1056,9 @@ void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_na
        struct libusb_context *ctx;
 
        usbi_mutex_static_lock(&active_contexts_lock);
-       usbi_mutex_static_lock(&hotplug_lock);
        list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
                linux_enumerate_device(ctx, busnum, devaddr, sys_name);
        }
-       usbi_mutex_static_unlock(&hotplug_lock);
        usbi_mutex_static_unlock(&active_contexts_lock);
 }
 
@@ -1071,7 +1069,6 @@ void linux_hotplug_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys
        unsigned long session_id = busnum << 8 | devaddr;
 
        usbi_mutex_static_lock(&active_contexts_lock);
-       usbi_mutex_static_lock(&hotplug_lock);
        list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
                dev = usbi_get_device_by_session_id (ctx, session_id);
                if (NULL != dev) {
@@ -1080,7 +1077,6 @@ void linux_hotplug_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys
                        usbi_dbg("device not found for session %x", session_id);
                }
        }
-       usbi_mutex_static_unlock(&hotplug_lock);
        usbi_mutex_static_unlock(&active_contexts_lock);
 }
 
index 5003bab..8525418 100644 (file)
@@ -146,6 +146,8 @@ struct usbfs_hub_portinfo {
 #define IOCTL_USBFS_RELEASE_PORT       _IOR('U', 25, unsigned int)
 #define IOCTL_USBFS_GET_CAPABILITIES   _IOR('U', 26, __u32)
 
+extern usbi_mutex_static_t linux_hotplug_lock;
+
 #if defined(HAVE_LIBUDEV)
 int linux_udev_start_event_monitor(void);
 int linux_udev_stop_event_monitor(void);
index 297caf8..8064f14 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10722
+#define LIBUSB_NANO 10723