From ee5421470a92d66ff79098f68e2ceb99c4cbfd3c Mon Sep 17 00:00:00 2001 From: TazyFoundSoup Date: Thu, 11 Jun 2026 19:07:19 +1000 Subject: fix(thread): Add mutex to ff_ctx and make ff_dprintf thread-safe --- include/tinyff/common.h | 9 +++++++++ src/common.c | 16 ++++++++++++++++ src/dbg.c | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/include/tinyff/common.h b/include/tinyff/common.h index 2b17911..6d93a70 100644 --- a/include/tinyff/common.h +++ b/include/tinyff/common.h @@ -8,6 +8,10 @@ #include #include +#ifdef USE_THREAD +#include +#endif + #ifdef USE_BENCH #include @@ -128,6 +132,11 @@ typedef struct ff_ctx { #ifdef USE_BENCH ff_bench bench; #endif + + #ifdef USE_THREAD + /* mutex to protect ctx internal mutable state when threads are enabled */ + pthread_mutex_t ff_lock; + #endif } ff_ctx; ff_ctx* ff_init(ff_allocator* allocator); diff --git a/src/common.c b/src/common.c index bde1bac..f9e46d5 100644 --- a/src/common.c +++ b/src/common.c @@ -6,6 +6,9 @@ #include #endif +#ifdef USE_THREAD +#include +#endif // Initializes a new tinyff context. ff_ctx* ff_init(ff_allocator* allocator) @@ -27,12 +30,25 @@ ff_ctx* ff_init(ff_allocator* allocator) ctx->allocator = *allocator; +#ifdef USE_THREAD + /* initialize mutex used to protect ctx state */ + if (pthread_mutex_init(&ctx->ff_lock, NULL) != 0) { + ctx->allocator.ff_free(ctx); + return NULL; + } +#endif + return ctx; } void ff_cleanup(ff_ctx *ctx) { if (!ctx) return; ff_dprintf(ctx, "goodbye from tinyff ;]\n"); + +#ifdef USE_THREAD + pthread_mutex_destroy(&ctx->ff_lock); +#endif + ctx->allocator.ff_free(ctx); } diff --git a/src/dbg.c b/src/dbg.c index a12545d..13c3f18 100644 --- a/src/dbg.c +++ b/src/dbg.c @@ -3,6 +3,10 @@ #include #include +#ifdef USE_THREAD +#include +#endif + static size_t ff_internal_itoa(int value, char* buf) { char temp[12]; @@ -52,6 +56,9 @@ static inline void ff_debug_flush(ff_ctx* ctx, char* buffer, size_t* idx) { if (*idx == 0) return; +#ifdef USE_THREAD + pthread_mutex_lock(&ctx->ff_lock); +#endif ctx->ff_debug_stream.write( buffer, *idx, @@ -59,6 +66,9 @@ static inline void ff_debug_flush(ff_ctx* ctx, char* buffer, size_t* idx) ); *idx = 0; +#ifdef USE_THREAD + pthread_mutex_unlock(&ctx->ff_lock); +#endif } ff_result ff_dprintf(ff_ctx* ctx, const char *format, ...) @@ -74,6 +84,10 @@ ff_result ff_dprintf(ff_ctx* ctx, const char *format, ...) size_t buf_idx = 0; const char* p = format; +#ifdef USE_THREAD + pthread_mutex_lock(&ctx->ff_lock); +#endif + while (*p) { if (buf_idx >= sizeof(buffer) - 64) { @@ -152,6 +166,10 @@ ff_result ff_dprintf(ff_ctx* ctx, const char *format, ...) ff_debug_flush(ctx, buffer, &buf_idx); +#ifdef USE_THREAD + pthread_mutex_unlock(&ctx->ff_lock); +#endif + va_end(args); return FF_RESULT_OK; } \ No newline at end of file -- cgit v1.2.3