Avoid double-scheduling build edges in another case
The change in commit v1.2.0~3^2~3^2~3 (Fix duplicate edge Pool crash in
the minimally invasive way, 2013-03-18) avoids double-scheduling in a
case involving duplicate out edges. However, double-scheduling may also
occur on a consistent graph when an edge and one of its dependencies
share an order-only input:
$ cat build.ninja
...
build c: touch
build b: touch || c
build a: touch | b || c
$ ninja a
$ rm a c
$ ninja a
In this case 'c' will build first. When NodeFinished('c') loops over
the out edges it will find AllInputsReady is true for 'b' and call
EdgeFinished('b') since it is not wanted (up to date). This will
call NodeFinished('b') which will loop over its out edges, find
AllInputsReady is true for 'a', and call ScheduleEdge('a'). When
we eventually return to the loop in NodeFinished('c') it will move
on to its second output and find that AllInputsReady is true for
'a' and call ScheduleEdge('a') again.
Teach ScheduleEdge to tolerate duplicate calls for an edge that has
already been scheduled. Avoid calling EdgeScheduled more than once
for the same edge.