diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2013-10-16 14:46:35 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2013-10-16 14:46:35 +0200 |
commit | 4bd52825734face53df2ab00052d2457d31c3c68 (patch) | |
tree | c11cdc04ddb14c261d8ec2e83fa61db7abe5c213 /src/libstore | |
parent | bce14d0f61801f0f1c3080970619e2ca11683a4e (diff) |
Convenience macros for retrying a SQLite transaction
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/local-store.cc | 88 |
1 files changed, 42 insertions, 46 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index f88af10f7..15200e842 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -75,6 +75,11 @@ static void throwSQLiteError(sqlite3 * db, const format & f) } +/* Convenience macros for retrying a SQLite transaction. */ +#define retry_sqlite while (1) { try { +#define end_retry_sqlite break; } catch (SQLiteBusy & e) { } } + + SQLite::~SQLite() { try { @@ -1219,39 +1224,33 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos) * expense of some speed of the path registering operation. */ if (settings.syncBeforeRegistering) sync(); - while (1) { - try { - SQLiteTxn txn(db); - PathSet paths; + retry_sqlite { + SQLiteTxn txn(db); + PathSet paths; + + foreach (ValidPathInfos::const_iterator, i, infos) { + assert(i->hash.type == htSHA256); + if (isValidPath(i->path)) + updatePathInfo(*i); + else + addValidPath(*i); + paths.insert(i->path); + } - foreach (ValidPathInfos::const_iterator, i, infos) { - assert(i->hash.type == htSHA256); - if (isValidPath(i->path)) - updatePathInfo(*i); - else - addValidPath(*i); - paths.insert(i->path); - } + foreach (ValidPathInfos::const_iterator, i, infos) { + unsigned long long referrer = queryValidPathId(i->path); + foreach (PathSet::iterator, j, i->references) + addReference(referrer, queryValidPathId(*j)); + } - foreach (ValidPathInfos::const_iterator, i, infos) { - unsigned long long referrer = queryValidPathId(i->path); - foreach (PathSet::iterator, j, i->references) - addReference(referrer, queryValidPathId(*j)); - } + /* Do a topological sort of the paths. This will throw an + error if a cycle is detected and roll back the + transaction. Cycles can only occur when a derivation + has multiple outputs. */ + topoSortPaths(*this, paths); - /* Do a topological sort of the paths. This will throw an - error if a cycle is detected and roll back the - transaction. Cycles can only occur when a derivation - has multiple outputs. */ - topoSortPaths(*this, paths); - - txn.commit(); - break; - } catch (SQLiteBusy & e) { - /* Retry; the `txn' destructor will roll back the current - transaction. */ - } - } + txn.commit(); + } end_retry_sqlite; } @@ -1642,23 +1641,20 @@ void LocalStore::invalidatePathChecked(const Path & path) { assertStorePath(path); - while (1) { - try { - SQLiteTxn txn(db); - - if (isValidPath(path)) { - PathSet referrers; queryReferrers(path, referrers); - referrers.erase(path); /* ignore self-references */ - if (!referrers.empty()) - throw PathInUse(format("cannot delete path `%1%' because it is in use by %2%") - % path % showPaths(referrers)); - invalidatePath(path); - } + retry_sqlite { + SQLiteTxn txn(db); - txn.commit(); - break; - } catch (SQLiteBusy & e) { }; - } + if (isValidPath(path)) { + PathSet referrers; queryReferrers(path, referrers); + referrers.erase(path); /* ignore self-references */ + if (!referrers.empty()) + throw PathInUse(format("cannot delete path `%1%' because it is in use by %2%") + % path % showPaths(referrers)); + invalidatePath(path); + } + + txn.commit(); + } end_retry_sqlite; } |