Index: subversion/libsvn_fs_util/sqlite-util.c =================================================================== --- subversion/libsvn_fs_util/sqlite-util.c (revision 27961) +++ subversion/libsvn_fs_util/sqlite-util.c (working copy) @@ -26,6 +26,7 @@ #include +#include "svn_types.h" #include "svn_fs.h" #include "svn_path.h" #include "svn_mergeinfo.h" @@ -185,11 +186,45 @@ sqlite3_errmsg(db)); } +#ifndef SVN_HAVE_SQLITE_THREADSAFE_PREDICATE +#include +#endif + svn_error_t * svn_fs__sqlite_open(sqlite3 **db, const char *repos_path, apr_pool_t *pool) { - const char *db_path = svn_path_join(repos_path, - SVN_FS__SQLITE_DB_NAME, pool); + const char *db_path; + svn_boolean_t is_threadsafe = TRUE; + + /* SQLite 3.5 allows verification of its thread-safety at runtime. + Older versions are simply expected to have been compiled with + -DSQLITE_THREADSAFE=1 or -DTHREADSAFE. */ +#ifdef SVN_HAVE_SQLITE_THREADSAFE_PREDICATE + is_threadsafe = sqlite3_threadsafe(); +#else + /* Attempt to dynamically load sqlite3_threadsafe(). Since it + wasn't statically compiled into Subversion, the version of SQLite + present at compile-time may've changed.. */ + void *lib_handle = dlopen("libsqlite3.so", RTLD_NOW); + if (lib_handle) + { + int (*threadsafe_func)(void) = dlsym(lib_handle, "sqlite3_threadsafe"); + if (threadsafe_func) + is_threadsafe = (*threadsafe_func)(); + dlclose(lib_handle); + } + + /* Clear any the dynamic library-related failure. */ + dlerror(); +#endif + if (! is_threadsafe) + return svn_error_create(SVN_ERR_FS_SQLITE_ERROR, NULL, + _("SQLite is required to be compiled and run in " + "thread-safe mode")); + + db_path = svn_path_join(repos_path, SVN_FS__SQLITE_DB_NAME, pool); + + /* Open the database. */ SVN_FS__SQLITE_ERR(sqlite3_open(db_path, db), *db); /* Retry until timeout when database is busy. */ SVN_FS__SQLITE_ERR(sqlite3_busy_timeout(*db, BUSY_TIMEOUT), *db); Index: build/ac-macros/sqlite.m4 =================================================================== --- build/ac-macros/sqlite.m4 (revision 27961) +++ build/ac-macros/sqlite.m4 (working copy) @@ -52,6 +52,8 @@ svn_lib_sqlite="yes" SVN_SQLITE_INCLUDES="`$pkg_config $SQLITE_PKGNAME --cflags`" SVN_SQLITE_LIBS="`$pkg_config $SQLITE_PKGNAME --libs`" + AC_CHECK_LIB(sqlite3, sqlite3_threadsafe, + [threadsafety_runtime_check_avail=yes]) ;; *) AC_MSG_RESULT([none or unsupported $sqlite_version]) @@ -68,6 +70,11 @@ fi ]) + if test "$threadsafety_runtime_check_avail" = "yes"; then + AC_DEFINE([SVN_HAVE_SQLITE_THREADSAFE_PREDICATE], [1], + [Defined if SQLite 3.5+'s thread-safety runtime check is available.]) + fi + AC_SUBST(SVN_SQLITE_INCLUDES) AC_SUBST(SVN_SQLITE_LIBS) ]) @@ -94,8 +101,12 @@ else SVN_SQLITE_LIBS="-lsqlite3" fi - ]) ]) + AC_CHECK_LIB(sqlite3, sqlite3_threadsafe, + [threadsafety_runtime_check_avail=yes]) + ]) + ]) + if test "$sqlite_dir" != "" && test -d "$sqlite_dir"; then CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS"