]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
progressbar: Add mutex to avoid race when drawing
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 17 Aug 2022 08:52:19 +0000 (08:52 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 17 Aug 2022 08:52:19 +0000 (08:52 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/progressbar.c

index c4681bf693560d2fb2e2b1012bcc29b18414e839..8338e6f66783211c45ce2d704eda59c6f4bfb2c7 100644 (file)
@@ -19,6 +19,7 @@
 #############################################################################*/
 
 #include <errno.h>
+#include <pthread.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -75,6 +76,7 @@ struct pakfire_progressbar {
 
        struct timespec time_start;
        timer_t timer;
+       pthread_mutex_t drawlock;
 
        // Widgets
        STAILQ_HEAD(widgets, pakfire_progressbar_widget) widgets;
@@ -134,12 +136,21 @@ static void pakfire_progressbar_free(struct pakfire_progressbar* p) {
        if (p->timer)
                timer_delete(p->timer);
 
+       // Free muted
+       pthread_mutex_destroy(&p->drawlock);
+
        pakfire_progressbar_free_widgets(p);
        free(p);
 }
 
 static int pakfire_progressbar_draw(struct pakfire_progressbar* p) {
        struct pakfire_progressbar_widget* widget;
+       int r;
+
+       // Acquire the lock
+       r = pthread_mutex_lock(&p->drawlock);
+       if (r)
+               return r;
 
        // Update terminal size if not set
        if (!terminal.cols)
@@ -210,6 +221,9 @@ static int pakfire_progressbar_draw(struct pakfire_progressbar* p) {
        // Flush everything
        fflush(p->f);
 
+       // Release lock
+       pthread_mutex_unlock(&p->drawlock);
+
        return 0;
 }
 
@@ -222,6 +236,9 @@ static void __pakfire_progressbar_draw(union sigval data) {
 
 PAKFIRE_EXPORT int pakfire_progressbar_create(
                struct pakfire_progressbar** progressbar, FILE* f) {
+       int r;
+
+       // Allocate main object
        struct pakfire_progressbar* p = calloc(1, sizeof(*p));
        if (!p)
                return ENOMEM;
@@ -236,6 +253,11 @@ PAKFIRE_EXPORT int pakfire_progressbar_create(
        // Store output
        p->f = stdout;
 
+       // Acquire lock
+       r = pthread_mutex_init(&p->drawlock, NULL);
+       if (r)
+               goto ERROR;
+
        // Register signal handler to update terminal size
        signal(SIGWINCH, pakfire_progressbar_update_terminal_size);
 
@@ -251,7 +273,7 @@ PAKFIRE_EXPORT int pakfire_progressbar_create(
        };
 
        // Create timer
-       int r = timer_create(CLOCK_REALTIME, &sigevent, &p->timer);
+       r = timer_create(CLOCK_REALTIME, &sigevent, &p->timer);
        if (r)
                goto ERROR;