diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2012-02-13 21:51:10 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2012-02-13 21:51:10 +0400 |
commit | a5b48a05a94d178c342bbad69a330addb518d148 (patch) | |
tree | ee7ab452cd4a98fdb7503e78cc52a3d4f66dd27e /src/mem_pool.c | |
parent | 0d64c808b7310b6e233ec570649fbb281a3f2b13 (diff) | |
download | rspamd-a5b48a05a94d178c342bbad69a330addb518d148.tar.gz rspamd-a5b48a05a94d178c342bbad69a330addb518d148.zip |
* More things to be thread-safe:
- pool allocator is now thread-safe
- lua subsystem now holds lock to avoid lua stack corruption
- events subsystem now using conditional variables to wait for async_threads
- insert_result is thread-safe now
Diffstat (limited to 'src/mem_pool.c')
-rw-r--r-- | src/mem_pool.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/mem_pool.c b/src/mem_pool.c index d5b3ddf6e..c68ae4b13 100644 --- a/src/mem_pool.c +++ b/src/mem_pool.c @@ -41,6 +41,14 @@ pthread_mutex_t stat_mtx = PTHREAD_MUTEX_INITIALIZER; # define STAT_UNLOCK() do {} while (0) #endif +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30)) +# define POOL_MTX_LOCK() do { g_static_mutex_lock (&pool->mtx); } while (0) +# define POOL_MTX_UNLOCK() do { g_static_mutex_unlock (&pool->mtx); } while (0) +#else +# define POOL_MTX_LOCK() do { g_mutex_lock (&pool->mtx); } while (0) +# define POOL_MTX_UNLOCK() do { g_mutex_unlock (&pool->mtx); } while (0) +#endif + /* * This define specify whether we should check all pools for free space for new object * or just begin scan from current (recently attached) pool @@ -101,6 +109,7 @@ pool_chain_new_shared (gsize size) struct _pool_chain_shared *chain; gpointer map; + #if defined(HAVE_MMAP_ANON) map = mmap (NULL, size + sizeof (struct _pool_chain_shared), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); if (map == MAP_FAILED) { @@ -189,6 +198,11 @@ memory_pool_new (gsize size) new->destructors = NULL; /* Set it upon first call of set variable */ new->variables = NULL; +#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30)) + new->mtx = G_STATIC_MUTEX_INIT; +#else + g_mutex_init (&new->mtx); +#endif mem_pool_stat->pools_allocated++; @@ -203,6 +217,7 @@ memory_pool_alloc (memory_pool_t * pool, gsize size) gint free; if (pool) { + POOL_MTX_LOCK (); #ifdef MEMORY_GREEDY cur = pool->first_pool; #else @@ -214,6 +229,7 @@ memory_pool_alloc (memory_pool_t * pool, gsize size) } if (free < (gint)size && cur->next == NULL) { /* Allocate new pool */ + if (cur->len >= size + MEM_ALIGNMENT) { new = pool_chain_new (cur->len); } @@ -227,10 +243,12 @@ memory_pool_alloc (memory_pool_t * pool, gsize size) /* No need to align again */ tmp = new->pos; new->pos = tmp + size; + POOL_MTX_UNLOCK (); return tmp; } tmp = align_ptr (cur->pos, MEM_ALIGNMENT); cur->pos = tmp + size; + POOL_MTX_UNLOCK (); return tmp; } return NULL; @@ -317,6 +335,7 @@ memory_pool_alloc_shared (memory_pool_t * pool, gsize size) if (pool) { g_return_val_if_fail (size > 0, NULL); + POOL_MTX_LOCK (); cur = pool->shared_pool; if (!cur) { cur = pool_chain_new_shared (pool->first_pool->len); @@ -329,6 +348,7 @@ memory_pool_alloc_shared (memory_pool_t * pool, gsize size) } if (free < (gint)size && cur->next == NULL) { /* Allocate new pool */ + if (cur->len >= size + MEM_ALIGNMENT) { new = pool_chain_new_shared (cur->len); } @@ -342,10 +362,12 @@ memory_pool_alloc_shared (memory_pool_t * pool, gsize size) STAT_LOCK (); mem_pool_stat->bytes_allocated += size; STAT_UNLOCK (); + POOL_MTX_UNLOCK (); return new->begin; } tmp = align_ptr (cur->pos, MEM_ALIGNMENT); cur->pos = tmp + size; + POOL_MTX_UNLOCK (); return tmp; } return NULL; @@ -455,12 +477,14 @@ memory_pool_add_destructor_full (memory_pool_t * pool, pool_destruct_func func, cur = memory_pool_alloc (pool, sizeof (struct _pool_destructors)); if (cur) { + POOL_MTX_LOCK (); cur->func = func; cur->data = data; cur->function = function; cur->loc = line; cur->prev = pool->destructors; pool->destructors = cur; + POOL_MTX_UNLOCK (); } } @@ -488,6 +512,7 @@ memory_pool_delete (memory_pool_t * pool) struct _pool_chain_shared *cur_shared = pool->shared_pool, *tmp_shared; struct _pool_destructors *destructor = pool->destructors; + POOL_MTX_LOCK (); /* Call all pool destructors */ while (destructor) { /* Avoid calling destructors for NULL pointers */ @@ -522,6 +547,7 @@ memory_pool_delete (memory_pool_t * pool) } mem_pool_stat->pools_freed++; + POOL_MTX_UNLOCK (); g_slice_free (memory_pool_t, pool); } |