about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-12-10 18:23:25 -0800
committerEric Wong <normalperson@yhbt.net>2010-12-10 18:23:25 -0800
commit40b3033aa688a2758a0e958a65000e450d474f97 (patch)
tree56551c3690c9a1fa3864dd91e8085146be7d0341
parent56378c0fc1704cab0e0e1e6800befaf84e419b43 (diff)
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.
-rw-r--r--ext/tdb/extconf.rb2
-rw-r--r--ext/tdb/tdb.c18
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 <st.h>
 #endif
+#include <pthread.h>
 
+/* 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)