int pdict_add_persistent_change_listener(pdict_t *pd, const char *kpat, pdl_notify_func_t notify, void *arg) { pdict_persistent_listener_t *pl; static int lid = 1; if (!(pl = malloc(sizeof (*pl)))) return 0; memset(pl, 0, sizeof (*pl)); pl->pdpl_l.pdl_notify = notify; pl->pdpl_l.pdl_arg = arg; if (regcomp(&pl->pdpl_regex, kpat, REG_EXTENDED | REG_NOSUB) != 0) { // XXX todo: communicate error context is not libc free(pl); pl = NULL; pu_log(PUL_WARN, 0, "Failed regcomp in pdict_add_persistent_change_listener."); return 0; } plist_add((void *)(size_t)lid, pl, &pd->pd_persistent_listeners); pl->pdpl_new = 1; if (!_pdict_walk_int(pd, pdict_ent_add_persistent_change_listener_dcb, pl)) { _pdict_walk_int(pd, pdict_ent_remove_persistent_change_listener_dcb, pl); plist_remove((void *)(size_t)lid, &pd->pd_persistent_listeners, NULL); regfree(&pl->pdpl_regex); free(pl); pl = NULL; pu_log(PUL_WARN, 0, "Failed _pdict_walk_int in pdict_add_persistent_change_listener."); return 0; } pl->pdpl_new = 0; return lid++; }
static Clause extract_given_clause(Plist *lst) { Clause c = first_lightest(*lst); *lst = plist_remove(*lst, c); return c; } /* extract_given_clause */
static int _pdict_ent_remove_change_listener(pdict_ent_t *pde, pdl_notify_func_t notify, void *a) { void *arg[3]; arg[0] = (void *)notify; arg[1] = a; arg[2] = NULL; plist_walk(pde->pde_listeners, pdict_ent_remove_change_listener_cb, arg); if (arg[2]) { plist_remove(arg[2], &pde->pde_listeners, NULL); free(arg[2]); arg[2] = NULL; return 1; } return 0; }
int pdict_remove_persistent_change_listener(pdict_t *pd, int id) { pdict_persistent_listener_t *pdpl; if (!plist_remove((void *)(size_t)id, &pd->pd_persistent_listeners, (void **)&pdpl) || !pdpl) { pu_log(PUL_WARN, 0, "Failed plist_remove in pdict_remove_persistent_change_listener."); return 0; } if (!_pdict_walk_int(pd, pdict_ent_remove_persistent_change_listener_dcb, pdpl)) { pu_log(PUL_WARN, 0, "Failed _pdict_walk_int in pdict_remove_persistent_change_listener."); return 0; } regfree(&pdpl->pdpl_regex); free(pdpl); pdpl = NULL; return 1; }