Skip to content

Commit

Permalink
[fixes #15] pkgdb_lock/unlock handles specific sqlite3_exec exit codes
Browse files Browse the repository at this point in the history
pkgdb_lock/unlock now use sqlite3_exec instead of sql_exec (see #15)
  • Loading branch information
scher committed Aug 7, 2012
1 parent 47ec185 commit 8535662
Showing 1 changed file with 30 additions and 12 deletions.
42 changes: 30 additions & 12 deletions libpkg/pkgdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -3668,6 +3668,9 @@ pkgdb_lock(struct pkgdb *db)
assert(db != NULL);
assert(!db->locked);

int sql_ret = SQLITE_OK;
int ret = EPKG_OK;
char * errmsg = NULL;
int64_t lock_t, lock_attempts_n;
if ( (pkg_config_int64(PKG_CONFIG_DB_LOCK_T, &lock_t) != EPKG_OK) ||
(pkg_config_int64(PKG_CONFIG_DB_LOCK_ATTEMPTS, &lock_attempts_n) !=
Expand All @@ -3678,20 +3681,35 @@ pkgdb_lock(struct pkgdb *db)
assert(lock_t > 0);

while (true) {
if (sql_exec(db->sqlite, "PRAGMA main.locking_mode=EXCLUSIVE;BEGIN IMMEDIATE;COMMIT;")
== EPKG_OK) {
db->locked = true;
return EPKG_OK;
} else {
if (--lock_attempts_n ==0)
break;
// wait a bit if the database is locked by other pkgng process
sleep(lock_t);
sql_ret = sqlite3_exec(db->sqlite,
"PRAGMA main.locking_mode=EXCLUSIVE;BEGIN IMMEDIATE;COMMIT;",
NULL, NULL, &errmsg);
switch (sql_ret) {
case SQLITE_OK:
db->locked = true;
return EPKG_OK;
break;
case SQLITE_BUSY:
if (--lock_attempts_n ==0) {
// if unable to lock a db after lock_attempts_n
// handle it here
ret = EPKG_FATAL;
goto cleanup;
}
// wait a bit if the database is locked by other pkgng process
sleep(lock_t);
break;
default:
// unhandled error code of sqlite transaction
ret = EPKG_FATAL;
goto cleanup;
break;
}
}
// TODO: if unable to lock a db after lock_attempts_n
// hangle it here
return EPKG_FATAL;
cleanup:
pkg_emit_error("sqlite: %s", errmsg);
sqlite3_free(errmsg);
return ret;
}

int
Expand Down

0 comments on commit 8535662

Please sign in to comment.