- fix segfault in "fallback" solution creation code, do two passes to find better...
authorMichael Schroeder <mls@suse.de>
Tue, 26 Jul 2011 13:30:00 +0000 (15:30 +0200)
committerMichael Schroeder <mls@suse.de>
Tue, 26 Jul 2011 13:30:00 +0000 (15:30 +0200)
src/problems.c

index 1d9689c..6a5e979 100644 (file)
@@ -220,7 +220,7 @@ refine_suggestion(Solver *solv, Id *problem, Id sug, Queue *refined, int essenti
 
   for (;;)
     {
-      int njob, nfeature, nupdate;
+      int njob, nfeature, nupdate, pass;
       queue_empty(&solv->problems);
       solver_reset(solv);
 
@@ -235,28 +235,39 @@ refine_suggestion(Solver *solv, Id *problem, Id sug, Queue *refined, int essenti
       disabledcnt = disabled.count;
       /* start with 1 to skip over proof index */
       njob = nfeature = nupdate = 0;
-      for (i = 1; i < solv->problems.count - 1; i++)
+      for (pass = 0; pass < 2; pass++)
        {
-         /* ignore solutions in refined */
-          v = solv->problems.elements[i];
-         if (v == 0)
-           break;      /* end of problem reached */
-         for (j = 0; problem[j]; j++)
-           if (problem[j] != sug && problem[j] == v)
-             break;
-         if (problem[j])
-           continue;
-         if (v >= solv->featurerules && v < solv->featurerules_end)
-           nfeature++;
-         else if (v > 0)
-           nupdate++;
-         else
+         for (i = 1; i < solv->problems.count - 1; i++)
            {
-             if (!essentialok && (solv->job.elements[-v -1] & SOLVER_ESSENTIAL) != 0)
-               continue;       /* not that one! */
-             njob++;
+             /* ignore solutions in refined */
+             v = solv->problems.elements[i];
+             if (v == 0)
+               break;  /* end of problem reached */
+             if (sug != v)
+               {
+                 /* check if v is in the given problems list
+                  * we allow disabling all problem rules *after* sug in
+                  * pass 2, to prevent getting the same solution twice */
+                 for (j = 0; problem[j]; j++)
+                   if (problem[j] == v || (pass && problem[j] == sug))
+                     break;
+                 if (problem[j] == v)
+                   continue;
+               }
+             if (v >= solv->featurerules && v < solv->featurerules_end)
+               nfeature++;
+             else if (v > 0)
+               nupdate++;
+             else
+               {
+                 if (!essentialok && (solv->job.elements[-v -1] & SOLVER_ESSENTIAL) != 0)
+                   continue;   /* not that one! */
+                 njob++;
+               }
+             queue_push(&disabled, v);
            }
-         queue_push(&disabled, v);
+         if (disabled.count != disabledcnt)
+           break;
        }
       if (disabled.count == disabledcnt)
        {
@@ -580,9 +591,7 @@ create_solutions(Solver *solv, int probnr, int solidx)
          queue_push(&solv->solutions, 0);
          for (j = 0; j < problem.count; j++)
            {
-             queue_empty(&solution);
-             queue_push(&solution, problem.elements[j]);
-             convertsolution(solv, solution.elements[j], &solv->solutions);
+             convertsolution(solv, problem.elements[j], &solv->solutions);
              if (solv->solutions.count > solstart + 1)
                break;
            }