diff options
author | Akira TAGOH <akira@tagoh.org> | 2017-12-18 20:05:14 +0900 |
---|---|---|
committer | Akira TAGOH <akira@tagoh.org> | 2017-12-18 20:05:14 +0900 |
commit | 8ab4d679959815feb0c383e1e17953fe1c46091f (patch) | |
tree | ed516896998b3f2c0a02adafa708e63e1592f60b /src | |
parent | 0378790ca362757061bff83c8a344991f1f829c6 (diff) |
Replace uuid in the table properly when -r
Diffstat (limited to 'src')
-rw-r--r-- | src/fccache.c | 7 | ||||
-rw-r--r-- | src/fchash.c | 37 | ||||
-rw-r--r-- | src/fcint.h | 4 |
3 files changed, 42 insertions, 6 deletions
diff --git a/src/fccache.c b/src/fccache.c index c9e72566..dfe9520f 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -62,6 +62,7 @@ FcDirCacheCreateUUID (FcChar8 *dir, int fd; uuid_t uuid; char out[37]; + FcBool (* hash_add) (FcHashTable *, void*, void*); atomic = FcAtomicCreate (uuidname); if (!atomic) @@ -81,7 +82,11 @@ FcDirCacheCreateUUID (FcChar8 *dir, goto bail3; } uuid_generate_random (uuid); - if (!FcHashTableAdd (config->uuid_table, dir, uuid)) + if (force) + hash_add = FcHashTableReplace; + else + hash_add = FcHashTableAdd; + if (!hash_add (config->uuid_table, dir, uuid)) { ret = FcFalse; goto bail3; diff --git a/src/fchash.c b/src/fchash.c index 54e23344..32e59c5a 100644 --- a/src/fchash.c +++ b/src/fchash.c @@ -137,10 +137,11 @@ FcHashTableFind (FcHashTable *table, return FcFalse; } -FcBool -FcHashTableAdd (FcHashTable *table, - void *key, - void *value) +static FcBool +FcHashTableAddInternal (FcHashTable *table, + void *key, + void *value, + FcBool replace) { FcHashBucket **prev, *bucket, *b; FcChar32 hash = table->hash_func (key); @@ -167,17 +168,43 @@ FcHashTableAdd (FcHashTable *table, table->value_destroy_func (bucket->value); free (bucket); - return FcFalse; + return !ret; } retry: for (prev = &table->buckets[hash % FC_HASH_SIZE]; (b = fc_atomic_ptr_get (prev)); prev = &(b->next)) { if (!table->compare_func (bucket->key, key)) + { + if (replace) + { + if (!fc_atomic_ptr_cmpexch (prev, b, bucket)) + goto retry; + bucket = b; + } + else + ret = FcTrue; goto destroy; + } } if (!fc_atomic_ptr_cmpexch (prev, b, bucket)) goto retry; return FcTrue; } + +FcBool +FcHashTableAdd (FcHashTable *table, + void *key, + void *value) +{ + return FcHashTableAddInternal (table, key, value, FcFalse); +} + +FcBool +FcHashTableReplace (FcHashTable *table, + void *key, + void *value) +{ + return FcHashTableAddInternal (table, key, value, FcTrue); +} diff --git a/src/fcint.h b/src/fcint.h index 3559ad6d..6185f5a8 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -1335,5 +1335,9 @@ FcHashTableAdd (FcHashTable *table, void *key, void *value); +FcPrivate FcBool +FcHashTableReplace (FcHashTable *table, + void *key, + void *value); #endif /* _FC_INT_H_ */ |