From 40b3033aa688a2758a0e958a65000e450d474f97 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 10 Dec 2010 18:23:25 -0800 Subject: [PATCH] enforce locking for TDB creation/destroy TDB objects aren't created often, so this shouldn't be noticeable, and there's no other way if any notion of thread-safety is desired. --- ext/tdb/extconf.rb | 2 ++ ext/tdb/tdb.c | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ext/tdb/extconf.rb b/ext/tdb/extconf.rb index 5359f7d..f7bb223 100644 --- a/ext/tdb/extconf.rb +++ b/ext/tdb/extconf.rb @@ -9,5 +9,7 @@ have_library('tdb') or abort 'libtdb missing' have_func('tdb_jenkins_hash') have_func('tdb_repack') have_const('TDB_ERR_NESTING', 'tdb.h') +have_header('pthread.h') +have_library('pthread') create_makefile('tdb_ext') diff --git a/ext/tdb/tdb.c b/ext/tdb/tdb.c index 196e29d..a502d3b 100644 --- a/ext/tdb/tdb.c +++ b/ext/tdb/tdb.c @@ -8,7 +8,10 @@ #else # include #endif +#include +/* this protects the global list of tdb objects maintained by libtdb */ +static pthread_mutex_t big_lock = PTHREAD_MUTEX_INITIALIZER; static VALUE cTDB, cERR; static st_table *exc_hash; static VALUE hashes; @@ -116,8 +119,12 @@ static void gcfree(void *ptr) { struct tdb_context *tdb = ptr; - if (tdb) + /* no error checking in GC :< */ + if (tdb) { + (void)pthread_mutex_lock(&big_lock); (void)tdb_close(tdb); + (void)pthread_mutex_unlock(&big_lock); + } } static VALUE alloc(VALUE klass) @@ -152,8 +159,10 @@ static VALUE nogvl_open(void *ptr) struct open_args *o = ptr; struct tdb_context *tdb; + pthread_mutex_lock(&big_lock); tdb = tdb_open_ex(o->name, o->hash_size, o->tdb_flags, o->open_flags, o->mode, o->log_ctx, o->hash_fn); + pthread_mutex_unlock(&big_lock); return (VALUE)tdb; } @@ -274,8 +283,13 @@ static VALUE init(int argc, VALUE *argv, VALUE self) static VALUE nogvl_close(void *ptr) { struct tdb_context *tdb = ptr; + VALUE rv; - return (VALUE)tdb_close(tdb); + pthread_mutex_lock(&big_lock); + rv = (VALUE)tdb_close(tdb); + pthread_mutex_unlock(&big_lock); + + return rv; } static VALUE tdbclose(VALUE self) -- 2.11.4.GIT