fix bug-1060 bug-1067

This commit is contained in:
Rongsong Shen 2026-06-24 17:05:43 +08:00
parent 6067ba6c94
commit 61e1391cd0
28 changed files with 7021 additions and 2926 deletions

View file

@ -42,20 +42,35 @@ int xce_add_hook(hooksys_t* s, int typ, hook_fn_t fn, void* data)
return -EINVAL;
}
/* Scan for a disabled (NULL-fn) slot of the same type to reuse */
/* Single scan of the type's slots:
* - if (fn,data) is ALREADY registered and active, adding again is a
* no-op (idempotent). xce_disable_hook removes only ONE matching slot
* and xce_run_hooks fires ALL slots, so a duplicate (fn,data) would
* fire twice and survive a single disable — the bug-845 double-append
* (persist_start + ha_register_persist_hooks both register the same
* persist_job_hook_fun closure). Dedup is keyed on (fn,data): the same
* fn with a DISTINCT closure stays a legitimate second registration.
* - otherwise remember the first disabled (NULL-fn) slot to reuse. */
{
xlist_t* l = &s->hooks[typ];
int i;
xlist_t* l = &s->hooks[typ];
hook_item_t* reuse = NULL;
int i;
for (i = 0; i < l->count; i++) {
hook_item_t* slot = (hook_item_t*)l->data[i];
if (!slot) continue;
hook_fn_t cur =
atomic_load_explicit(&slot->fn, memory_order_acquire);
if (cur == NULL) {
slot->data = data;
atomic_store_explicit(&slot->fn, fn, memory_order_release);
return 0;
if (!reuse) reuse = slot;
continue;
}
if (cur == fn && slot->data == data)
return 0; /* already registered — no duplicate */
}
if (reuse != NULL) {
reuse->data = data;
atomic_store_explicit(&reuse->fn, fn, memory_order_release);
return 0;
}
}