summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2012-02-28 09:39:35 +0200
committerTimo Teräs <timo.teras@iki.fi>2012-02-28 09:39:35 +0200
commit536c21979b59a10592c7be0674be4c88a97e8d83 (patch)
tree5ba983c2ad2970bce10aa1153711a7c284f621a2 /src
parentb7a22e555f7d287edec0ae7c816de16ca74d2941 (diff)
downloadapk-tools-536c21979b59a10592c7be0674be4c88a97e8d83.tar.gz
apk-tools-536c21979b59a10592c7be0674be4c88a97e8d83.tar.bz2
apk-tools-536c21979b59a10592c7be0674be4c88a97e8d83.tar.xz
apk-tools-536c21979b59a10592c7be0674be4c88a97e8d83.zip
solver: allow multiple packages with same virtual provides
ref #574
Diffstat (limited to 'src')
-rw-r--r--src/solver.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/solver.c b/src/solver.c
index 50bea4c..9084b1d 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -116,6 +116,7 @@ struct apk_name_state {
unsigned short requirers;
unsigned short install_ifs;
unsigned short preferred_pinning;
+ unsigned short locked;
/* one time prepare/finish flags */
unsigned solver_flags_local : 4;
@@ -129,7 +130,6 @@ struct apk_name_state {
/* dynamic state flags */
unsigned none_excluded : 1;
- unsigned locked : 1;
unsigned name_touched : 1;
};
@@ -761,9 +761,14 @@ static inline void assign_name(
{
struct apk_name_state *ns = name_to_ns(name);
- ASSERT(!ns->locked, "Assigning locked name");
- ns->locked = 1;
+ if (p.version == &apk_null_blob) {
+ ASSERT(!ns->locked || ns->chosen.version == &apk_null_blob,
+ "Assigning locked name with version");
+ } else {
+ ASSERT(!ns->locked, "Assigning locked name");
+ }
ns->chosen = p;
+ ns->locked++;
if (list_hashed(&ns->unsolved_list)) {
list_del(&ns->unsolved_list);
list_init(&ns->unsolved_list);
@@ -775,11 +780,12 @@ static inline void unassign_name(struct apk_solver_state *ss, struct apk_name *n
struct apk_name_state *ns = name_to_ns(name);
ASSERT(ns->locked, "Unassigning unlocked name");
- ns->locked = 0;
- ns->chosen = CHOSEN_NONE;
- ns->name_touched = 1;
-
- demote_name(ss, name);
+ ns->locked--;
+ if (ns->locked == 0) {
+ ns->chosen = CHOSEN_NONE;
+ ns->name_touched = 1;
+ demote_name(ss, name);
+ }
}