| | @@ -171,18 +171,42 @@ |
| 171 | 171 | foreach succ [$cset successors] { |
| 172 | 172 | # Changesets may have dependencies outside of the |
| 173 | 173 | # chosen set. These are ignored |
| 174 | 174 | if {![$dg node exists $succ]} continue |
| 175 | 175 | $dg arc insert $cset $succ |
| 176 | + |
| 177 | + # Check for changesets referencing themselves. Such a |
| 178 | + # loop shows that the changeset in question has |
| 179 | + # internal dependencies. Something which is supposed |
| 180 | + # to be not possible, as pass 5 (InitCsets) takes care |
| 181 | + # to transform internal into external dependencies by |
| 182 | + # breaking the relevant changesets apart. So having |
| 183 | + # one indicates big trouble in pass 5. We report them |
| 184 | + # and dump internal structures to make it easier to |
| 185 | + # trace the links causing the problem. |
| 186 | + if {$succ eq $cset} { |
| 187 | + trouble fatal "Self-referencing changeset <[$cset id]>" |
| 188 | + log write 2 cyclebreaker "LOOP changeset <[$cset id]> __________________" |
| 189 | + array set nmap [$cset nextmap] |
| 190 | + foreach r [lsort -dict [array names nmap]] { |
| 191 | + foreach succrev $nmap($r) { |
| 192 | + log write 2 cyclebreaker \ |
| 193 | + "LOOP * rev <$r> --> rev <$succrev> --> cs [join [struct::list map [project::rev ofrev $succrev] [myproc ID]] { }]" |
| 194 | + } |
| 195 | + } |
| 196 | + } |
| 176 | 197 | } |
| 177 | 198 | } |
| 178 | 199 | |
| 179 | 200 | # Run the user hook to manipulate the graph before |
| 180 | 201 | # consummation. |
| 181 | 202 | |
| 182 | 203 | if {$log} { Mark $dg -start } |
| 183 | 204 | PreHook $dg |
| 205 | + |
| 206 | + # This kills the application if loops (see above) were found. |
| 207 | + trouble abort? |
| 184 | 208 | return $dg |
| 185 | 209 | } |
| 186 | 210 | |
| 187 | 211 | # Instead of searching the whole graph for the degree-0 nodes in |
| 188 | 212 | # each iteration we compute the list once to start, and then only |
| | @@ -282,10 +306,11 @@ |
| 282 | 306 | # The cycle we have gotten is broken by breaking apart one or |
| 283 | 307 | # more of the changesets in the cycle. This causes us to |
| 284 | 308 | # create one or more changesets which are to be committed, |
| 285 | 309 | # added to the graph, etc. pp. |
| 286 | 310 | |
| 311 | + # NOTE/TODO. Move this map operation to project::rev, as typemethod. |
| 287 | 312 | set cprint [join [struct::list map $cycle [myproc ID]] { }] |
| 288 | 313 | |
| 289 | 314 | lappend cycle [lindex $cycle 0] [lindex $cycle 1] |
| 290 | 315 | set bestlink {} |
| 291 | 316 | set bestnode {} |
| | @@ -373,10 +398,13 @@ |
| 373 | 398 | foreach succ [$cset successors] { |
| 374 | 399 | # The new changesets may have dependencies outside of |
| 375 | 400 | # the chosen set. These are ignored |
| 376 | 401 | if {![$dg node exists $succ]} continue |
| 377 | 402 | $dg arc insert $cset $succ |
| 403 | + if {$succ eq $cset} { |
| 404 | + trouble internal "Self-referencing changeset <[$cset id]>" |
| 405 | + } |
| 378 | 406 | } |
| 379 | 407 | } |
| 380 | 408 | foreach cset $pre { |
| 381 | 409 | foreach succ [$cset successors] { |
| 382 | 410 | # Note that the arc may already exist in the graph. If |
| 383 | 411 | |