diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2011-12-30 14:47:14 +0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2011-12-30 14:47:14 +0000 |
commit | b1004f40f7e4dd02feec2d0cb26bd6c95dd66dde (patch) | |
tree | 185519967aa2ef3c9a03309d9838d5418eb1d2a3 /src/libstore/gc.cc | |
parent | 254b3399ba3d7cf161fa54f9cf6cdc65c17164fb (diff) |
* Reject a build if there is a cycle among the outputs. This is
necessary because existing code assumes that the references graph is
acyclic.
Diffstat (limited to 'src/libstore/gc.cc')
-rw-r--r-- | src/libstore/gc.cc | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index feaab573e..ec7751133 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -372,8 +372,13 @@ static void addAdditionalRoots(StoreAPI & store, PathSet & roots) static void dfsVisit(StoreAPI & store, const PathSet & paths, - const Path & path, PathSet & visited, Paths & sorted) + const Path & path, PathSet & visited, Paths & sorted, + PathSet & parents) { + if (parents.find(path) != parents.end()) + throw BuildError(format("cycle detected in the references of `%1%'") % path); + parents.insert(path); + if (visited.find(path) != visited.end()) return; visited.insert(path); @@ -385,18 +390,19 @@ static void dfsVisit(StoreAPI & store, const PathSet & paths, /* Don't traverse into paths that don't exist. That can happen due to substitutes for non-existent paths. */ if (*i != path && paths.find(*i) != paths.end()) - dfsVisit(store, paths, *i, visited, sorted); + dfsVisit(store, paths, *i, visited, sorted, parents); sorted.push_front(path); + parents.erase(path); } Paths topoSortPaths(StoreAPI & store, const PathSet & paths) { Paths sorted; - PathSet visited; + PathSet visited, parents; foreach (PathSet::const_iterator, i, paths) - dfsVisit(store, paths, *i, visited, sorted); + dfsVisit(store, paths, *i, visited, sorted, parents); return sorted; } |