/* * Create and insert new contact * into urecord */ int insert_ucontact(urecord_t* _r, str* aor, str* _c, time_t _e, qvalue_t _q, str* _cid, int _cs, unsigned int _flags, struct ucontact** _con, str* _ua, str* _recv, struct socket_info* sock, str* _inst, int sid) { if (mem_insert_ucontact(_r, aor, _c, _e, _q, _cid, _cs, _flags, _con, _ua, _recv, sock, _inst, sid) < 0) { LOG(L_ERR, "insert_ucontact(): Error while inserting contact\n"); return -1; } notify_watchers(_r, *_con, (_e > 0) ? PRES_ONLINE : PRES_OFFLINE); if (exists_ulcb_type(UL_CONTACT_INSERT)) { run_ul_callbacks( UL_CONTACT_INSERT, *_con); } save_reg_avps(*_con); if (db_mode == WRITE_THROUGH) { if (db_store_ucontact(*_con) < 0) { LOG(L_ERR, "insert_ucontact(): Error while inserting in database\n"); } (*_con)->state = CS_SYNC; } return 0; }
void thread_impl_t::set_state( THREAD_STATE state ) { ULONG prev_state = ThreadState; if (prev_state == StateTerminated) return; ThreadState = state; switch (state) { case StateWait: runlist_remove(); break; case StateRunning: runlist_add(); break; case StateTerminated: notify_watchers(); if (prev_state == StateRunning) runlist_remove(); break; default: die("switch to unknown thread state\n"); } // ready to complete some I/O? if (num_active_threads() == 0) check_completions(); }
void event_impl_t::set( PULONG prev ) { *prev = state; state = 1; notify_watchers(); }
/* * This timer routine is used when * db_mode is set to NO_DB */ static inline int nodb_timer(urecord_t* _r) { ucontact_t* ptr, *t; int not = 0; ptr = _r->contacts; while(ptr) { if (ptr->expires < act_time) { if (ptr->replicate != 0) { LOG(L_NOTICE, "Keeping binding '%.*s','%.*s' for replication\n", ptr->aor->len, ZSW(ptr->aor->s), ptr->c.len, ZSW(ptr->c.s)); /* keep it for replication, but it expired normaly * and was the last contact, so notify */ if (!ptr->next && ptr->state == CS_NEW) not=1; ptr = ptr->next; } else { LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n", ptr->aor->len, ZSW(ptr->aor->s), ptr->c.len, ZSW(ptr->c.s)); t = ptr; ptr = ptr->next; /* it was the last contact and it was in normal * state, so notify */ if (!ptr && t->state == CS_NEW) not=1; mem_delete_ucontact(_r, t); _r->slot->d->expired++; } /* Last contact expired, notify watchers */ if (not) notify_watchers(_r, PRES_OFFLINE); } else { /* the contact was unregistered and is not marked * for replication so remove it, but the notify was * done during unregister */ if (ptr->state == CS_ZOMBIE_N && ptr->replicate == 0) { LOG(L_NOTICE, "removing spare zombie '%.*s','%.*s'\n", ptr->aor->len, ZSW(ptr->aor->s), ptr->c.len, ZSW(ptr->c.s)); t = ptr; ptr = ptr->next; mem_delete_ucontact(_r, t); } else ptr = ptr->next; } } return 0; }
static void apteryx__prune (Apteryx__Server_Service *service, const Apteryx__Prune *prune, Apteryx__OKResult_Closure closure, void *closure_data) { Apteryx__OKResult result = APTERYX__OKRESULT__INIT; result.result = 0; GList *paths = NULL, *iter; (void) service; /* Check parameters */ if (prune == NULL || prune->path == NULL) { ERROR ("PRUNE: Invalid parameters.\n"); result.result = -EINVAL; closure (&result, closure_data); INC_COUNTER (counters.prune_invalid); return; } INC_COUNTER (counters.prune); DEBUG ("PRUNE: %s\n", prune->path); /* Proxy first */ if (proxy_prune (prune->path)) { /* Return result */ closure (&result, closure_data); return; } /* Collect the list of deleted paths for notification */ paths = g_list_prepend(paths, g_strdup(prune->path)); _search_paths (&paths, prune->path); /* Prune from database */ db_delete (prune->path, UINT64_MAX); /* Return result */ closure (&result, closure_data); /* Call watchers for each pruned path */ for (iter = paths; iter; iter = g_list_next (iter)) { notify_watchers ((const char *)iter->data); } g_list_free_full (paths, g_free); return; }
/* * This routine is used when db_mode is * set to WRITE_THROUGH */ static inline int wt_timer(urecord_t* _r) { ucontact_t* ptr, *t; int not = 0; ptr = _r->contacts; while(ptr) { if (!VALID_CONTACT(ptr, act_time)) { /* run callbacks for EXPIRE event */ if (exists_ulcb_type(UL_CONTACT_EXPIRE)) { run_ul_callbacks( UL_CONTACT_EXPIRE, ptr); } notify_watchers(_r, ptr, PRES_OFFLINE); LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n", ptr->uid->len, ZSW(ptr->uid->s), ptr->c.len, ZSW(ptr->c.s)); t = ptr; ptr = ptr->next; /* it was the last contact and it was in normal * state, so notify */ if (!ptr && t->state == CS_SYNC) not=1; if (db_delete_ucontact(t) < 0) { LOG(L_ERR, "wt_timer(): Error while deleting contact from " "database\n"); } delete_reg_avps(t); mem_delete_ucontact(_r, t); _r->slot->d->expired++; } else { /* the contact was unregistered and is not marked * for replication so remove it, but the notify was * already done during unregister */ ptr = ptr->next; } } return 0; }
/* * Create and insert new contact * into urecord */ int insert_ucontact_rep(urecord_t* _r, str* _c, time_t _e, float _q, str* _cid, int _cs, unsigned int _flags, int _rep, struct ucontact** _con) { if (mem_insert_ucontact(_r, _c, _e, _q, _cid, _cs, _flags, _rep, _con) < 0) { LOG(L_ERR, "insert_ucontact(): Error while inserting contact\n"); return -1; } notify_watchers(_r, PRES_ONLINE); if (db_mode == WRITE_THROUGH) { if (db_insert_ucontact(*_con) < 0) { LOG(L_ERR, "insert_ucontact(): Error while inserting in database\n"); mem_delete_ucontact(_r, *_con); return -2; } (*_con)->state=CS_SYNC; } return 0; }
/* * Delete ucontact from urecord */ int delete_ucontact(urecord_t* _r, struct ucontact* _c) { if (exists_ulcb_type(UL_CONTACT_DELETE)) { run_ul_callbacks( UL_CONTACT_DELETE, _c); } notify_watchers(_r, _c, PRES_OFFLINE); if (st_delete_ucontact(_c) > 0) { if (db_mode == WRITE_THROUGH) { if (db_delete_ucontact(_c) < 0) { LOG(L_ERR, "delete_ucontact(): Can't remove contact from " "database\n"); } } delete_reg_avps(_c); mem_delete_ucontact(_r, _c); } return 0; }
/* * Delete ucontact from urecord */ int delete_ucontact(urecord_t* _r, struct ucontact* _c) { struct ucontact* ptr; if (st_delete_ucontact(_c) > 0) { if (db_mode == WRITE_THROUGH) { if (db_delete_ucontact(_c) < 0) { LOG(L_ERR, "delete_ucontact(): Can't remove contact from " "database\n"); } } mem_delete_ucontact(_r, _c); } ptr = _r->contacts; while(ptr) { if (ptr->state < CS_ZOMBIE_N) return 0; ptr = ptr->next; } notify_watchers(_r, PRES_OFFLINE); return 0; }
/* * This timer routine is used when * db_mode is set to NO_DB or READONLY */ static inline int nodb_timer(urecord_t* _r) { ucontact_t* ptr, *t; int not = 0; ptr = _r->contacts; while(ptr) { if (!VALID_CONTACT(ptr, act_time)) { /* run callbacks for EXPIRE event */ if (exists_ulcb_type(UL_CONTACT_EXPIRE)) run_ul_callbacks( UL_CONTACT_EXPIRE, ptr); notify_watchers(_r, ptr, PRES_OFFLINE); LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n", ptr->uid->len, ZSW(ptr->uid->s), ptr->c.len, ZSW(ptr->c.s)); t = ptr; ptr = ptr->next; /* it was the last contact and it was in normal * state, so notify */ if (!ptr && t->state == CS_NEW) not=1; delete_reg_avps(t); mem_delete_ucontact(_r, t); _r->slot->d->expired++; } else { ptr = ptr->next; } } return 0; }
/* * Write-back timer */ static inline int wb_timer(urecord_t* _r) { ucontact_t* ptr, *t; int op; int not = 0; ptr = _r->contacts; while(ptr) { if (!VALID_CONTACT(ptr, act_time)) { /* run callbacks for EXPIRE event */ if (exists_ulcb_type(UL_CONTACT_EXPIRE)) { run_ul_callbacks( UL_CONTACT_EXPIRE, ptr); } notify_watchers(_r, ptr, PRES_OFFLINE); LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n", ptr->uid->len, ZSW(ptr->uid->s), ptr->c.len, ZSW(ptr->c.s)); if (ptr->next == 0) not=1; _r->slot->d->expired++; t = ptr; ptr = ptr->next; /* Should we remove the contact from the database ? */ if (st_expired_ucontact(t) == 1) { if (db_delete_ucontact(t) < 0) { LOG(L_ERR, "wb_timer(): Can't delete contact from the database\n"); } } delete_reg_avps(t); mem_delete_ucontact(_r, t); } else { /* Determine the operation we have to do */ op = st_flush_ucontact(ptr); switch(op) { case 0: /* do nothing, contact is synchronized */ break; case 1: /* insert */ if (db_store_ucontact(ptr) < 0) { LOG(L_ERR, "wb_timer(): Error while inserting contact into database\n"); } break; case 2: /* update */ if (db_store_ucontact(ptr) < 0) { LOG(L_ERR, "wb_timer(): Error while updating contact in db\n"); } break; case 4: /* delete */ if (db_delete_ucontact(ptr) < 0) { LOG(L_ERR, "wb_timer(): Can't delete contact from database\n"); } /* fall through to the next case statement */ case 3: /* delete from memory */ delete_reg_avps(ptr); mem_delete_ucontact(_r, ptr); break; } ptr = ptr->next; } } return 0; }
static void apteryx__set (Apteryx__Server_Service *service, const Apteryx__Set *set, Apteryx__OKResult_Closure closure, void *closure_data) { Apteryx__OKResult result = APTERYX__OKRESULT__INIT; const char *path = NULL; const char *value = NULL; result.result = 0; int validation_result = 0; int validation_lock = 0; int proxy_result = 0; bool db_result = false; int i; /* Check parameters */ if (set == NULL || set->n_sets == 0 || set->sets == NULL) { ERROR ("SET: Invalid parameters.\n"); result.result = -EINVAL; closure (&result, closure_data); INC_COUNTER (counters.set_invalid); return; } INC_COUNTER (counters.set); /* Debug */ for (i=0; apteryx_debug && i<set->n_sets; i++) { DEBUG ("SET: %s = %s\n", set->sets[i]->path, set->sets[i]->value); } /* Proxy first */ for (i=0; i<set->n_sets; i++) { path = set->sets[i]->path; value = set->sets[i]->value; if (value && value[0] == '\0') value = NULL; proxy_result = proxy_set (path, value, set->ts); if (proxy_result == 0) { /* Result success */ DEBUG ("SET: %s = %s proxied\n", path, value); /* Mark the set as processed */ notify_watchers (set->sets[i]->path); free (set->sets[i]->path); set->sets[i]->path = NULL; } else if (proxy_result < 0) { result.result = proxy_result; goto exit; } } /* Validate */ for (i=0; i<set->n_sets; i++) { path = set->sets[i]->path; if (!path) continue; value = set->sets[i]->value; if (value && value[0] == '\0') value = NULL; /* Validate new data */ validation_result = validate_set (path, value); if (validation_result != 0) validation_lock++; if (validation_result < 0) { DEBUG ("SET: %s = %s refused by validate\n", path, value); result.result = validation_result; goto exit; } } /* Set in the database */ pthread_rwlock_wrlock (&db_lock); for (i=0; i<set->n_sets; i++) { path = set->sets[i]->path; if (!path) continue; value = set->sets[i]->value; if (value && value[0] == '\0') value = NULL; /* Add/Delete to/from database */ if (value) db_result = db_add_no_lock (path, (unsigned char*)value, strlen (value) + 1, set->ts); else db_result = db_delete_no_lock (path, set->ts); if (!db_result) { DEBUG ("SET: %s = %s refused by DB\n", path, value); result.result = -EBUSY; pthread_rwlock_unlock (&db_lock); goto exit; } } pthread_rwlock_unlock (&db_lock); /* Set succeeded */ result.result = 0; exit: /* Return result and notify watchers */ if (validation_result >= 0 && result.result == 0) { /* Notify watchers */ for (i=0; i<set->n_sets; i++) { if (set->sets[i]->path) notify_watchers (set->sets[i]->path); } } /* Return result */ closure (&result, closure_data); /* Release validation lock - this is a sensitive value */ while (validation_lock) { DEBUG("SET: unlocking mutex\n"); pthread_mutex_unlock (&validating); validation_lock--; } return; }
/* * Write-back timer */ static inline int wb_timer(urecord_t* _r) { ucontact_t* ptr, *t; int op; int not = 0; ptr = _r->contacts; while(ptr) { if (ptr->expires < act_time) { if (ptr->replicate != 0) { LOG(L_NOTICE, "Keeping binding '%.*s','%.*s' for " "replication\n", ptr->aor->len, ZSW(ptr->aor->s), ptr->c.len, ZSW(ptr->c.s)); /* keep it for replication, but it expired normaly * and was the last contact, so notify */ if (!ptr->next && ptr->state < CS_ZOMBIE_N) not=1; ptr = ptr->next; } else { /* state == ZOMBIE the contact was remove by user */ if (ptr->state < CS_ZOMBIE_N) { LOG(L_NOTICE, "Binding '%.*s','%.*s' has expired\n", ptr->aor->len, ZSW(ptr->aor->s), ptr->c.len, ZSW(ptr->c.s)); if (ptr->next == 0) not=1; _r->slot->d->expired++; } t = ptr; ptr = ptr->next; /* Should we remove the contact from the database ? */ if (st_expired_ucontact(t) == 1) { if (db_delete_ucontact(t) < 0) { LOG(L_ERR, "wb_timer(): Can't delete contact from the database\n"); } } mem_delete_ucontact(_r, t); } if (not) notify_watchers(_r, PRES_OFFLINE); } else { /* Determine the operation we have to do */ op = st_flush_ucontact(ptr); switch(op) { case 0: /* do nothing, contact is synchronized */ break; case 1: /* insert */ if (db_insert_ucontact(ptr) < 0) { LOG(L_ERR, "wb_timer(): Error while inserting contact into database\n"); } break; case 2: /* update */ if (db_update_ucontact(ptr) < 0) { LOG(L_ERR, "wb_timer(): Error while updating contact in db\n"); } break; case 3: /* delete from memory */ mem_delete_ucontact(_r, ptr); break; case 4: /* delete */ if (db_delete_ucontact(ptr) < 0) { LOG(L_ERR, "wb_timer(): Can't delete contact from database\n"); } mem_delete_ucontact(_r, ptr); break; } ptr = ptr->next; } } return 0; }