You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/modules/p_usrloc/ul_check.c

197 lines
4.7 KiB

/* sp-ul_db module
*
* Copyright (C) 2007 1&1 Internet AG
*
* This file is part of Kamailio, a free SIP server.
*
* Kamailio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* Kamailio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../mem/shm_mem.h"
#include "ul_check.h"
#include "time.h"
static struct check_list_head * head = NULL;
static struct check_list_element * initialise_element(void);
static void destroy_element(struct check_list_element * element);
int init_list(void) {
if(!head){
if((head = (struct check_list_head *)shm_malloc(sizeof(struct check_list_head))) == NULL){
LM_ERR("couldn't allocate shared memory.\n");
return -1;
}
}
memset(head, 0, sizeof(struct check_list_head));
if(lock_init(&head->list_lock) == 0){
LM_ERR("cannot initialise lock.\n");
shm_free(head);
return -1;
}
return 0;
}
struct check_data * get_new_element(void) {
struct check_list_element * ret;
if(!head){
LM_ERR("list not initialised.\n");
return NULL;
}
LM_DBG("start.\n");
lock_get(&head->list_lock);
if((ret = initialise_element()) == NULL){
lock_release(&head->list_lock);
return NULL;
}
head->element_count++;
if(head->first == NULL){
LM_DBG("new element is the first.\n");
LM_DBG("element_count: %i\n", head->element_count);
head->first = ret;
lock_release(&head->list_lock);
return ret->data;
}
LM_DBG("new element.\n");
LM_DBG("element_count: %i\n", head->element_count);
ret->next = head->first;
head->first = ret;
lock_release(&head->list_lock);
return ret->data;
}
int must_refresh(struct check_data * element) {
int ret;
lock_get(&element->flag_lock);
ret = element->refresh_flag;
LM_DBG("refresh_flag is at %i.\n", ret);
element->refresh_flag = 0;
lock_release(&element->flag_lock);
return ret;
}
int must_reconnect(struct check_data * element) {
int ret;
lock_get(&element->flag_lock);
ret = element->reconnect_flag;
LM_DBG("reconnect_flag is at %i.\n", ret);
element->reconnect_flag = 0;
lock_release(&element->flag_lock);
return ret;
}
int set_must_refresh(void) {
struct check_list_element * tmp;
int i = 0;
lock_get(&head->list_lock);
tmp = head->first;
while(tmp){
lock_get(&tmp->data->flag_lock);
tmp->data->refresh_flag = 1;
lock_release(&tmp->data->flag_lock);
tmp = tmp->next;
i++;
LM_DBG("element no %i.\n", i);
}
lock_release(&head->list_lock);
return i;
}
int set_must_reconnect(void) {
struct check_list_element * tmp;
int i = 0;
lock_get(&head->list_lock);
tmp = head->first;
while(tmp){
lock_get(&tmp->data->flag_lock);
tmp->data->reconnect_flag = 1;
lock_release(&tmp->data->flag_lock);
tmp = tmp->next;
i++;
LM_DBG("element no %i.\n", i);
}
lock_release(&head->list_lock);
return i;
}
int must_retry(time_t * timer, time_t interval){
if(!timer){
return -1;
}
LM_DBG("must_retry: time is at %i, retry at %i.\n", (int)time(NULL), (int)(*timer));
if(*timer <= time(NULL)){
*timer = time(NULL) + interval;
return 1;
}
return 0;
}
void destroy_list(void) {
struct check_list_element * tmp;
struct check_list_element * del;
if(head){
tmp = head->first;
while(tmp){
del = tmp;
tmp = tmp->next;
destroy_element(del);
}
lock_destroy(&head->list_lock);
shm_free(head);
}
return;
}
static struct check_list_element * initialise_element(void){
struct check_list_element * ret;
if((ret = (struct check_list_element *)shm_malloc(sizeof(struct check_list_element))) == NULL){
LM_ERR("couldn't allocate shared memory.\n");
return NULL;
}
memset(ret, 0, sizeof(struct check_list_element));
if((ret->data = (struct check_data *)shm_malloc(sizeof(struct check_data))) == NULL){
LM_ERR("couldn't allocate shared memory.\n");
shm_free(ret);
return NULL;
}
memset(ret->data, 0, sizeof(struct check_data));
if(lock_init(&ret->data->flag_lock) == 0){
LM_ERR("cannot initialise flag lock.\n");
shm_free(ret->data);
shm_free(ret);
return NULL;
}
return ret;
}
static void destroy_element(struct check_list_element * element){
if(element){
if(element->data){
/* if(element->data->flag_lock){ */
lock_destroy(&element->data->flag_lock);
/* }*/
shm_free(element->data);
}
shm_free(element);
}
return;
}