struct noti_cb {
vconf_callback_fn cb;
void *user_data;
- int ref_cnt;
+ bool active;
+ bool in_cb;
};
static bool last_result;
for (l = noti->noti_list, n = g_list_next(l);
l; l = n, n = g_list_next(n)) {
struct noti_cb *noticb = l->data;
- noticb->ref_cnt--;
- if (noticb->ref_cnt == 0) {
+ noticb->active = false;
+
+ if (!noticb->in_cb) {
noti->noti_list = g_list_delete_link(noti->noti_list, l);
free(noticb);
}
pthread_mutex_lock(&vconf_lock);
for (l = noti_list; l; l = g_list_next(l)) {
struct noti_cb *noticb = l->data;
- noticb->ref_cnt++;
+ noticb->in_cb = true;
}
copy = g_list_copy(noti_list);
pthread_mutex_unlock(&vconf_lock);
for (l = noti_list, ll = g_list_next(l); l;
l = ll, ll = g_list_next(ll)) {
struct noti_cb *noticb = l->data;
+ noticb->in_cb = false;
- noticb->ref_cnt--;
- if (noticb->ref_cnt == 0) {
+ if (!noticb->active) {
noti_list = g_list_delete_link(noti_list, l);
free(noticb);
}
noticb = find_noti_cb(noti, cb);
if (noticb) {
- errno = EEXIST;
- return -1;
+ if (noticb->active) {
+ errno = EEXIST;
+ return -1;
+ } else {
+ noticb->active = true;
+ return 0;
+ }
}
noticb = calloc(1, sizeof(*noticb));
noticb->cb = cb;
noticb->user_data = user_data;
- noticb->ref_cnt = 1;
+ noticb->active = true;
+ noticb->in_cb = false;
noti->noti_list = g_list_append(noti->noti_list, noticb);
noti = g_hash_table_lookup(noti_tbl, key);
if (!noti) {
+ _close();
pthread_mutex_unlock(&vconf_lock);
errno = ENOENT;
return -1;
}
noticb = find_noti_cb(noti, cb);
- if (!noticb) {
+ if (!noticb || !noticb->active) {
+ _close();
pthread_mutex_unlock(&vconf_lock);
errno = ENOENT;
return -1;
}
- noticb->ref_cnt--;
- if (noticb->ref_cnt == 0) {
+ noticb->active = false;
+ if (!noticb->in_cb) {
noti->noti_list = g_list_remove(noti->noti_list, noticb);
free(noticb);
}
cnt = unregister_noti(noti);
if (cnt > 0) {
+ _close();
pthread_mutex_unlock(&vconf_lock);
return 0;
}