With this patch, variable's context is always honored in all operations,
FIND/ENTER (including delete).

Signed-off-by: AKASHI Takahiro <takahiro.aka...@linaro.org>
---
 include/search.h |  6 +++++-
 lib/hashtable.c  | 14 +++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/search.h b/include/search.h
index 0469a852e07c..202cf652de5f 100644
--- a/include/search.h
+++ b/include/search.h
@@ -25,13 +25,16 @@ enum env_action {
        ENV_ENTER,
 };
 
+struct env_context;
+
 /** struct env_entry - An entry in the environment hashtable */
 struct env_entry {
        const char *key;
        char *data;
        int (*callback)(const char *name, const char *value, enum env_op op,
-               int flags);
+                       int flags);
        int flags;
+       struct env_context *ctx;
 };
 
 /*
@@ -45,6 +48,7 @@ struct hsearch_data {
        struct env_entry_node *table;
        unsigned int size;
        unsigned int filled;
+       struct env_context *ctx;
 /*
  * Callback function which will check whether the given change for variable
  * "item" to "newval" may be applied or not, and possibly apply such change.
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 2caab0a4c6d3..8fe017470256 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -231,6 +231,7 @@ static inline int _compare_and_overwrite_entry(struct 
env_entry item,
                unsigned int idx)
 {
        if (htab->table[idx].used == hval
+           && (item.ctx && (item.ctx == htab->table[idx].entry.ctx))
            && strcmp(item.key, htab->table[idx].entry.key) == 0) {
                /* Overwrite existing value? */
                if (action == ENV_ENTER && item.data) {
@@ -247,8 +248,9 @@ static inline int _compare_and_overwrite_entry(struct 
env_entry item,
 
                        /* If there is a callback, call it */
                        if (htab->table[idx].entry.callback &&
-                           htab->table[idx].entry.callback(item.key,
-                           item.data, env_op_overwrite, flag)) {
+                           htab->table[idx].entry.callback(item.key, item.data,
+                                                           env_op_overwrite,
+                                                           flag)) {
                                debug("callback() rejected setting variable "
                                        "%s, skipping it!\n", item.key);
                                __set_errno(EINVAL);
@@ -340,6 +342,9 @@ int hsearch_r(struct env_entry item, enum env_action action,
                        if (idx == hval)
                                break;
 
+                       if (htab->table[idx].used == USED_FREE)
+                               break;
+
                        if (htab->table[idx].used == USED_DELETED
                            && !first_deleted)
                                first_deleted = idx;
@@ -381,6 +386,7 @@ int hsearch_r(struct env_entry item, enum env_action action,
                        *retval = NULL;
                        return 0;
                }
+               htab->table[idx].entry.ctx = item.ctx;
 
                ++htab->filled;
 
@@ -403,7 +409,7 @@ int hsearch_r(struct env_entry item, enum env_action action,
                /* If there is a callback, call it */
                if (htab->table[idx].entry.callback &&
                    htab->table[idx].entry.callback(item.key, item.data,
-                   env_op_create, flag)) {
+                                                   env_op_create, flag)) {
                        debug("callback() rejected setting variable "
                                "%s, skipping it!\n", item.key);
                        _hdelete(item.key, htab, &htab->table[idx].entry, idx);
@@ -454,6 +460,7 @@ int hdelete_r(const char *key, struct hsearch_data *htab, 
int flag)
 
        debug("hdelete: DELETE key \"%s\"\n", key);
 
+       e.ctx = htab->ctx;
        e.key = (char *)key;
 
        idx = hsearch_r(e, ENV_FIND, &ep, htab, 0);
@@ -928,6 +935,7 @@ int himport_r(struct hsearch_data *htab,
                        continue;
 
                /* enter into hash table */
+               e.ctx = htab->ctx;
                e.key = name;
                e.data = value;
 
-- 
2.21.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to