From a6fcc96249bfdca59ff2f328e2388e48aba0fd6c Mon Sep 17 00:00:00 2001 From: wangxp006 Date: Thu, 21 May 2026 14:57:12 +0800 Subject: [PATCH] fix: concurrency/deadlock issues in histogram, barrier, options and eventgen thread - sb_histogram.c: fix missing pthread_rwlock_unlock on early return in sb_histogram_print(), which caused a deadlock when maxcnt == 0 - sb_barrier.c: fix pthread_mutex leak when pthread_cond_init fails after pthread_mutex_init succeeds - sysbench.c: fix pthread_mutex leak in eventgen_thread_proc on the same mutex/cond init pattern - sb_options.c: replace non-thread-safe strtok() with strtok_r() for parsing list option values --- src/sb_barrier.c | 8 ++++++-- src/sb_histogram.c | 3 +++ src/sb_options.c | 3 ++- src/sysbench.c | 9 +++++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/sb_barrier.c b/src/sb_barrier.c index 8c901a7fc..8725719da 100644 --- a/src/sb_barrier.c +++ b/src/sb_barrier.c @@ -40,9 +40,13 @@ int sb_barrier_init(sb_barrier_t *barrier, unsigned int count, if (count == 0) return 1; - if (pthread_mutex_init(&barrier->mutex, NULL) || - pthread_cond_init(&barrier->cond, NULL)) + if (pthread_mutex_init(&barrier->mutex, NULL)) return 1; + if (pthread_cond_init(&barrier->cond, NULL)) + { + pthread_mutex_destroy(&barrier->mutex); + return 1; + } barrier->init_count = count; barrier->count = count; diff --git a/src/sb_histogram.c b/src/sb_histogram.c index 88c9ad6fe..57642cd3e 100644 --- a/src/sb_histogram.c +++ b/src/sb_histogram.c @@ -309,7 +309,10 @@ void sb_histogram_print(sb_histogram_t *h) } if (maxcnt == 0) + { + pthread_rwlock_unlock(&h->lock); return; + } printf(" value ------------- distribution ------------- count\n"); diff --git a/src/sb_options.c b/src/sb_options.c index 855c3323e..8f0876e16 100644 --- a/src/sb_options.c +++ b/src/sb_options.c @@ -165,10 +165,11 @@ option_t *set_option(const char *name, const char *value, sb_arg_type_t type) if (value == NULL) break; + char *saveptr; tmpbuf = strdup(value); tmp = tmpbuf; - for (tmp = strtok(tmp, ","); tmp != NULL; tmp = strtok(NULL, ",")) + for (tmp = strtok_r(tmp, ",", &saveptr); tmp != NULL; tmp = strtok_r(NULL, ",", &saveptr)) add_value(&opt->values, tmp); free(tmpbuf); diff --git a/src/sysbench.c b/src/sysbench.c index fb83bef45..3e376a205 100644 --- a/src/sysbench.c +++ b/src/sysbench.c @@ -865,12 +865,17 @@ static void *eventgen_thread_proc(void *arg) ck_ring_init(&queue_ring, MAX_QUEUE_LEN); - if (pthread_mutex_init(&queue_mutex, NULL) || - pthread_cond_init(&queue_cond, NULL)) + if (pthread_mutex_init(&queue_mutex, NULL)) { sb_barrier_wait(&worker_barrier); return NULL; } + if (pthread_cond_init(&queue_cond, NULL)) + { + pthread_mutex_destroy(&queue_mutex); + sb_barrier_wait(&worker_barrier); + return NULL; + } log_text(LOG_DEBUG, "Event generating thread started");