]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
libfrog: fix missing error checking in workqueue code
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 15 Oct 2019 16:54:35 +0000 (12:54 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Tue, 15 Oct 2019 16:54:35 +0000 (12:54 -0400)
Fix all the places in the workqueue code where we fail to check return
values and blindly keep going when we shouldn't.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libfrog/workqueue.c

index a806da3e63fa8a9f83651519e4ee67e60e01c519..48038363ebd08da4b5b0d5bdc7e064913b197f28 100644 (file)
@@ -67,12 +67,20 @@ workqueue_create(
        int                     err = 0;
 
        memset(wq, 0, sizeof(*wq));
-       pthread_cond_init(&wq->wakeup, NULL);
-       pthread_mutex_init(&wq->lock, NULL);
+       err = pthread_cond_init(&wq->wakeup, NULL);
+       if (err)
+               return err;
+       err = pthread_mutex_init(&wq->lock, NULL);
+       if (err)
+               goto out_cond;
 
        wq->wq_ctx = wq_ctx;
        wq->thread_count = nr_workers;
        wq->threads = malloc(nr_workers * sizeof(pthread_t));
+       if (!wq->threads) {
+               err = errno;
+               goto out_mutex;
+       }
        wq->terminate = false;
 
        for (i = 0; i < nr_workers; i++) {
@@ -82,9 +90,19 @@ workqueue_create(
                        break;
        }
 
+       /*
+        * If we encounter errors here, we have to signal and then wait for all
+        * the threads that may have been started running before we can destroy
+        * the workqueue.
+        */
        if (err)
                workqueue_destroy(wq);
        return err;
+out_mutex:
+       pthread_mutex_destroy(&wq->lock);
+out_cond:
+       pthread_cond_destroy(&wq->wakeup);
+       return err;
 }
 
 /*
@@ -99,6 +117,7 @@ workqueue_add(
        void                    *arg)
 {
        struct workqueue_item   *wi;
+       int                     ret;
 
        if (wq->thread_count == 0) {
                func(wq, index, arg);
@@ -118,9 +137,11 @@ workqueue_add(
        /* Now queue the new work structure to the work queue. */
        pthread_mutex_lock(&wq->lock);
        if (wq->next_item == NULL) {
-               wq->next_item = wi;
                assert(wq->item_count == 0);
-               pthread_cond_signal(&wq->wakeup);
+               ret = pthread_cond_signal(&wq->wakeup);
+               if (ret)
+                       goto out_item;
+               wq->next_item = wi;
        } else {
                wq->last_item->next = wi;
        }
@@ -129,6 +150,9 @@ workqueue_add(
        pthread_mutex_unlock(&wq->lock);
 
        return 0;
+out_item:
+       free(wi);
+       return ret;
 }
 
 /*