/* Don't call this function directly! Use svn_atomic__init_once(). */ static svn_error_t * init_sqlite(void *baton, apr_pool_t *pool) { if (sqlite3_libversion_number() < SQLITE_VERSION_NUMBER) { return svn_error_createf(SVN_ERR_SQLITE_ERROR, NULL, _("SQLite compiled for %s, but running with %s"), SQLITE_VERSION, sqlite3_libversion()); } #if APR_HAS_THREADS #if SQLITE_VERSION_AT_LEAST(3,5,0) /* SQLite 3.5 allows verification of its thread-safety at runtime. Older versions are simply expected to have been configured with --enable-threadsafe, which compiles with -DSQLITE_THREADSAFE=1 (or -DTHREADSAFE, for older versions). */ if (! sqlite3_threadsafe()) return svn_error_create(SVN_ERR_SQLITE_ERROR, NULL, _("SQLite is required to be compiled and run in " "thread-safe mode")); #endif #if SQLITE_VERSION_AT_LEAST(3,6,0) /* If SQLite has been already initialized, sqlite3_config() returns SQLITE_MISUSE. */ { int err = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); if (err != SQLITE_OK && err != SQLITE_MISUSE) return svn_error_create(SQLITE_ERROR_CODE(err), NULL, "Could not configure SQLite"); } SQLITE_ERR_MSG(sqlite3_initialize(), "Could not initialize SQLite"); #endif #endif /* APR_HAS_THRADS */ return SVN_NO_ERROR; }
static svn_error_t * internal_open(sqlite3 **db3, const char *path, svn_sqlite__mode_t mode, apr_pool_t *scratch_pool) { { int flags; if (mode == svn_sqlite__mode_readonly) flags = SQLITE_OPEN_READONLY; else if (mode == svn_sqlite__mode_readwrite) flags = SQLITE_OPEN_READWRITE; else if (mode == svn_sqlite__mode_rwcreate) flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; else SVN_ERR_MALFUNCTION(); /* If this flag is defined (3.6.x), then let's turn off SQLite's mutexes. All svn objects are single-threaded, so we can already guarantee that our use of the SQLite handle will be serialized properly. Note: in 3.6.x, we've already config'd SQLite into MULTITHREAD mode, so this is probably redundant, but if we are running in a process where somebody initialized SQLite before us it is needed anyway. */ #ifdef SQLITE_OPEN_NOMUTEX flags |= SQLITE_OPEN_NOMUTEX; #endif /* Open the database. Note that a handle is returned, even when an error occurs (except for out-of-memory); thus, we can safely use it to extract an error message and construct an svn_error_t. */ { /* We'd like to use SQLITE_ERR_MSG here, but we can't since it would just return an error and leave the database open. So, we need to do this manually. */ /* ### SQLITE_CANTOPEN */ int err_code = sqlite3_open_v2(path, db3, flags, NULL); if (err_code != SQLITE_OK) { /* Save the error message before closing the SQLite handle. */ char *msg = apr_pstrdup(scratch_pool, sqlite3_errmsg(*db3)); /* We don't catch the error here, since we care more about the open error than the close error at this point. */ sqlite3_close(*db3); return svn_error_createf(SQLITE_ERROR_CODE(err_code), NULL, "sqlite: %s: '%s'", msg, path); } } } /* Retry until timeout when database is busy. */ SQLITE_ERR_MSG(sqlite3_busy_timeout(*db3, BUSY_TIMEOUT), sqlite3_errmsg(*db3)); return SVN_NO_ERROR; }