Reputation: 15173
Is the sqlite3 Ruby gem thread safe? I can't find any documentation to say that it is.
In my experiments, accessing a database from multiple Ruby threads eventually leads to the following error:
/Library/Ruby/Gems/1.8/gems/sqlite3-ruby-1.2.5/lib/sqlite3/driver/native/driver.rb:84: [BUG] Bus Error
Is there anything I'm missing? If not, is there another package I can use that is thread safe?
Edit: using SQLite3.4 on Mac OS 10.5.
Upvotes: 1
Views: 1442
Reputation: 4702
It's most likely dependent on the sqlite3 library you're using. It can be compiled with thread safety on or off. The sqlite3_threadsafe() function will tell you, although I suspect that API is not exposed in the Ruby bindings.
The following C program would test it for you
#include <sqlite3.h>
#include <stdio.h>
int main()
{
printf("Threadsafe: %d\n", sqlite3_threadsafe());
}
Compile it with
gcc -o test test.c -lsqlite3
If it prints a non-zero number, then it should be threadsafe.
Upvotes: 3
Reputation: 15173
After some investigation, I found that the issue has nothing to do with sqlite3.
In the function that is performing the threaded access to the DB, an exception is occurring. As Thread.abort_on_exception defaults
to false, the exception is masked, but manifests as a bus error (see above) as soon as the DL function is evoked by driver.rb
Fixing the exception (a silly string/integer comparison) results in expected working behaviour - and using the test above did indicate that the sqlite lib was built with -DTHREADSAFE=1
Note I still have mutexes around the SQL queries as recommended by documents (see http://www.sqlite.org/cvstrac/wiki?p=MultiThreading ), but this may not be necessary with Ruby 1.8's "green" threads.
Upvotes: 0