/* 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; }