diff --git a/doc/libsolv-pool.txt b/doc/libsolv-pool.txt index 991083f38..860d16130 100644 --- a/doc/libsolv-pool.txt +++ b/doc/libsolv-pool.txt @@ -646,7 +646,10 @@ Utility functions Allocate space on the pool's temporary space area. This space has a limited lifetime, it will be automatically freed after a fixed amount (currently -16) of other pool_alloctmpspace() calls are done. +500) of other pool_alloctmpspace() calls are done. +The function is not completely thread-safe, but it mitigates the problem by +locking and using sufficiently large temporary space. That allows reading +from pool from several tens of concurrent threads. void pool_freetmpspace(Pool *pool, const char *space); diff --git a/src/pool.c b/src/pool.c index 0b4b9ddc1..813afb06d 100644 --- a/src/pool.c +++ b/src/pool.c @@ -1723,15 +1723,20 @@ pool_id2langid(Pool *pool, Id id, const char *lang, int create) char * pool_alloctmpspace(Pool *pool, int len) { - int n = pool->tmpspace.n; if (!len) return 0; + + pthread_mutex_lock(&pool->tmpspace.lock); + int n = pool->tmpspace.n; + pool->tmpspace.n = (n + 1) % POOL_TMPSPACEBUF; + pthread_mutex_unlock(&pool->tmpspace.lock); + if (len > pool->tmpspace.len[n]) { pool->tmpspace.buf[n] = solv_realloc(pool->tmpspace.buf[n], len + 32); pool->tmpspace.len[n] = len + 32; } - pool->tmpspace.n = (n + 1) % POOL_TMPSPACEBUF; + return pool->tmpspace.buf[n]; } diff --git a/src/pool.h b/src/pool.h index aa173ea17..7491d4ac0 100644 --- a/src/pool.h +++ b/src/pool.h @@ -13,6 +13,7 @@ #ifndef LIBSOLV_POOL_H #define LIBSOLV_POOL_H +#include #include #include "solvversion.h" @@ -53,12 +54,13 @@ typedef struct s_Datapos { #ifdef LIBSOLV_INTERNAL /* how many strings to maintain (round robin) */ -#define POOL_TMPSPACEBUF 16 +#define POOL_TMPSPACEBUF 500 struct s_Pool_tmpspace { char *buf[POOL_TMPSPACEBUF]; int len[POOL_TMPSPACEBUF]; int n; + pthread_mutex_t lock; }; #endif