Avoid race between ueventloop and uevqloop
authorBenjamin Marzinski <bmarzins@redhat.com>
Thu, 2 May 2013 21:46:29 +0000 (16:46 -0500)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Mon, 6 May 2013 19:41:08 +0000 (21:41 +0200)
ueventloop sets up uevq_lockp and uev_condp, which uevqloop uses.
If uevqloop accesses these structures before ueventloop has
initialized them, it will not wake up to process uevents. This patch
statically initializes these structures so they will always be
initialized. Also, since calling LIST_HEAD(uevq) initializes it,
there is no reason to call INIT_LIST_HEAD on it later.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
libmultipath/uevent.c

index bc74d38..0643e14 100644 (file)
@@ -53,8 +53,10 @@ typedef int (uev_trigger)(struct uevent *, void * trigger_data);
 
 pthread_t uevq_thr;
 LIST_HEAD(uevq);
 
 pthread_t uevq_thr;
 LIST_HEAD(uevq);
-pthread_mutex_t uevq_lock, *uevq_lockp = &uevq_lock;
-pthread_cond_t  uev_cond,  *uev_condp  = &uev_cond;
+pthread_mutex_t uevq_lock = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t *uevq_lockp = &uevq_lock;
+pthread_cond_t uev_cond = PTHREAD_COND_INITIALIZER;
+pthread_cond_t *uev_condp = &uev_cond;
 uev_trigger *my_uev_trigger;
 void * my_trigger_data;
 int servicing_uev;
 uev_trigger *my_uev_trigger;
 void * my_trigger_data;
 int servicing_uev;
@@ -409,10 +411,6 @@ int uevent_listen(void)
         * thereby not getting to empty the socket's receive buffer queue
         * often enough.
         */
         * thereby not getting to empty the socket's receive buffer queue
         * often enough.
         */
-       INIT_LIST_HEAD(&uevq);
-
-       pthread_mutex_init(uevq_lockp, NULL);
-       pthread_cond_init(uev_condp, NULL);
        pthread_cleanup_push(uevq_stop, NULL);
 
        monitor = udev_monitor_new_from_netlink(conf->udev, "udev");
        pthread_cleanup_push(uevq_stop, NULL);
 
        monitor = udev_monitor_new_from_netlink(conf->udev, "udev");
@@ -525,8 +523,6 @@ out:
        if (need_failback)
                err = failback_listen();
        pthread_cleanup_pop(1);
        if (need_failback)
                err = failback_listen();
        pthread_cleanup_pop(1);
-       pthread_mutex_destroy(uevq_lockp);
-       pthread_cond_destroy(uev_condp);
        return err;
 }
 
        return err;
 }