123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- /*
- * $Id$
- *
- * MSILO module
- *
- * Copyright (C) 2001-2003 FhG Fokus
- *
- * This file is part of ser, a free SIP server.
- *
- * ser 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
- *
- * For a license to use the ser software under conditions
- * other than those described here, or to purchase support for this
- * software, please contact iptel.org by e-mail at the following addresses:
- * [email protected]
- *
- * ser 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
- */
- /*
- * History:
- * --------
- * 2003-03-11 major locking changes: not it uses locking.h (andrei)
- */
- #include <string.h>
- #include <unistd.h>
- #include <stdio.h>
- #include "../../mem/mem.h"
- #include "../../mem/shm_mem.h"
- #include "../../dprint.h"
- #include "ms_msg_list.h"
- /**
- * create a new element
- */
- msg_list_el msg_list_el_new()
- {
- msg_list_el mle = NULL;
- mle = (msg_list_el)shm_malloc(sizeof(t_msg_list_el));
- if(mle == NULL)
- return NULL;
- mle->next = NULL;
- mle->prev = NULL;
- mle->msgid = 0;
- mle->flag = MS_MSG_NULL;
- return mle;
- }
- /**
- * free an element
- */
- void msg_list_el_free(msg_list_el mle)
- {
- if(mle)
- shm_free(mle);
- }
- /**
- * free a list of elements
- */
- void msg_list_el_free_all(msg_list_el mle)
- {
- msg_list_el p0, p1;
-
- if(!mle)
- return;
-
- p0 = mle;
- while(p0)
- {
- p1 = p0;
- p0 = p0->next;
- msg_list_el_free(p1);
- }
- }
- /**
- * init a list
- */
- msg_list msg_list_init()
- {
- msg_list ml = NULL;
-
- ml = (msg_list)shm_malloc(sizeof(t_msg_list));
- if(ml == NULL)
- return NULL;
- /* init locks */
- if (lock_init(&ml->sem_sent)==0){
- LOG(L_CRIT, "msilo: could not initialize a lock\n");
- goto clean;
- };
- if (lock_init(&ml->sem_done)==0){
- LOG(L_CRIT, "msilo: could not initialize a lock\n");
- lock_destroy(&ml->sem_sent);
- goto clean;
- };
- ml->nrsent = 0;
- ml->nrdone = 0;
- ml->lsent = NULL;
- ml->ldone = NULL;
-
- return ml;
- clean:
- shm_free(ml);
- return NULL;
- }
- /**
- * free a list
- */
- void msg_list_free(msg_list ml)
- {
- msg_list_el p0, p1;
- if(!ml)
- return;
- lock_destroy(&ml->sem_sent);
- lock_destroy(&ml->sem_done);
- if(ml->nrsent>0 && ml->lsent)
- { // free sent list
- p0 = ml->lsent;
- ml->lsent = NULL;
- ml->nrsent = 0;
- while(p0)
- {
- p1 = p0->next;
- msg_list_el_free(p0);
- p0 = p1;
- }
- }
- if(ml->nrdone>0 && ml->ldone)
- { // free done list
- p0 = ml->ldone;
- ml->ldone = NULL;
- ml->nrdone = 0;
- while(p0)
- {
- p1 = p0->next;
- msg_list_el_free(p0);
- p0 = p1;
- }
- }
-
- shm_free(ml);
- }
- /**
- * check if a message is in list
- */
- int msg_list_check_msg(msg_list ml, int mid)
- {
- msg_list_el p0, p1;
-
- if(!ml || mid==0)
- goto errorx;
- DBG("MSILO:msg_list_check_msg: checking msgid=%d\n", mid);
-
- lock_get(&ml->sem_sent);
- p0 = p1 = ml->lsent;
- while(p0)
- {
- if(p0->msgid==mid)
- goto exist;
- p1 = p0;
- p0 = p0->next;
- }
- p0 = msg_list_el_new();
- if(!p0)
- {
- DBG("MSILO:msg_list_check_msg: Error creating new msg elem.\n");
- goto error;
- }
- p0->msgid = mid;
- p0->flag |= MS_MSG_SENT;
- if(p1)
- {
- p1->next = p0;
- p0->prev = p1;
- goto done;
- }
-
- ml->lsent = p0;
-
- done:
- ml->nrsent++;
- lock_release(&ml->sem_sent);
- DBG("MSILO:msg_list_check_msg: msg added to sent list.\n");
- return MSG_LIST_OK;
- exist:
- lock_release(&ml->sem_sent);
- DBG("MSILO:msg_list_check_msg: msg already in sent list.\n");
- return MSG_LIST_EXIST;
- error:
- lock_release(&ml->sem_sent);
- errorx:
- return MSG_LIST_ERR;
- }
- /**
- * set flag for message with mid
- */
- int msg_list_set_flag(msg_list ml, int mid, int fl)
- {
- msg_list_el p0;
-
- if(!ml || mid==0)
- goto errorx;
-
- lock_get(&ml->sem_sent);
- p0 = ml->lsent;
- while(p0)
- {
- if(p0->msgid==mid)
- {
- p0->flag |= fl;
- DBG("MSILO: msg_list_set_flag: mid:%d fl:%d\n", p0->msgid, fl);
- goto done;
- }
- p0 = p0->next;
- }
- done:
- lock_release(&ml->sem_sent);
- return MSG_LIST_OK;
- errorx:
- return MSG_LIST_ERR;
- }
- /**
- * check if the messages from list were sent
- */
- int msg_list_check(msg_list ml)
- {
- msg_list_el p0;
- msg_list_el p0_next;
-
- if(!ml)
- goto errorx;
-
- lock_get(&ml->sem_sent);
- if(ml->nrsent<=0)
- goto done;
-
- lock_get(&ml->sem_done);
-
- p0 = ml->lsent;
- while(p0)
- {
- p0_next = p0->next;
- if(p0->flag & MS_MSG_DONE || p0->flag & MS_MSG_ERRO)
- {
- DBG("MSILO: msg_list_check: mid:%d got reply\n", p0->msgid);
- if(p0->prev)
- (p0->prev)->next = p0->next;
- else
- ml->lsent = p0->next;
- if(p0->next)
- (p0->next)->prev = p0->prev;
- ml->nrsent--;
- if(!ml->nrsent)
- ml->lsent = NULL;
- if(ml->ldone)
- (ml->ldone)->prev = p0;
- p0->next = ml->ldone;
-
- p0->prev = NULL;
- ml->ldone = p0;
- ml->nrdone++;
- }
- p0 = p0_next;
- }
- lock_release(&ml->sem_done);
- done:
- lock_release(&ml->sem_sent);
- return MSG_LIST_OK;
- errorx:
- return MSG_LIST_ERR;
- }
- /**
- * reset a list
- * return old list
- */
- msg_list_el msg_list_reset(msg_list ml)
- {
- msg_list_el p0;
-
- if(!ml)
- return NULL;
-
- lock_get(&ml->sem_done);
- p0 = ml->ldone;
- ml->ldone = NULL;
- ml->nrdone = 0;
- lock_release(&ml->sem_done);
-
- return p0;
- }
|