ms_msg_list.c

Go to the documentation of this file.
00001 /**
00002  * $Id: ms_msg_list.c 4518 2008-07-28 15:39:28Z henningw $
00003  *
00004  * MSILO module
00005  *
00006  * Copyright (C) 2001-2003 FhG Fokus
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * --------
00026  *  2003-03-11  major locking changes: not it uses locking.h (andrei)
00027  */
00028 
00029 #include <string.h>
00030 #include <unistd.h>
00031 #include <stdio.h>
00032 
00033 #include "../../mem/mem.h"
00034 #include "../../mem/shm_mem.h"
00035 #include "../../dprint.h"
00036 
00037 #include "ms_msg_list.h"
00038 
00039 /**
00040  * create a new element
00041  */
00042 msg_list_el msg_list_el_new(void)
00043 {
00044    msg_list_el mle = NULL;
00045    mle = (msg_list_el)shm_malloc(sizeof(t_msg_list_el));
00046    if(mle == NULL)
00047       return NULL;
00048 
00049    mle->next = NULL;
00050    mle->prev = NULL;
00051    mle->msgid = 0;
00052    mle->flag = MS_MSG_NULL;
00053 
00054    return mle;
00055 }
00056 
00057 /**
00058  * free an element
00059  */
00060 void msg_list_el_free(msg_list_el mle)
00061 {
00062    if(mle)
00063       shm_free(mle);
00064 }
00065 
00066 /**
00067  * free a list of elements
00068  */
00069 void msg_list_el_free_all(msg_list_el mle)
00070 {
00071    msg_list_el p0, p1;  
00072    
00073    if(!mle)
00074       return;
00075    
00076    p0 = mle;
00077    while(p0)
00078    {
00079       p1 = p0;
00080       p0 = p0->next;
00081       msg_list_el_free(p1);
00082    }
00083 }
00084 
00085 /**
00086  * init a list
00087  */
00088 msg_list msg_list_init(void)
00089 {
00090    msg_list ml = NULL;
00091    
00092    ml = (msg_list)shm_malloc(sizeof(t_msg_list));
00093    if(ml == NULL)
00094       return NULL;
00095    /* init locks */
00096    if (lock_init(&ml->sem_sent)==0){
00097       LM_CRIT("could not initialize a lock\n");
00098       goto clean;
00099    };
00100    if (lock_init(&ml->sem_done)==0){
00101       LM_CRIT("could not initialize a lock\n");
00102       lock_destroy(&ml->sem_sent);
00103       goto clean;
00104    };
00105    ml->nrsent = 0;
00106    ml->nrdone = 0;
00107    ml->lsent = NULL;
00108    ml->ldone = NULL;
00109    
00110    return ml;
00111 
00112 clean:
00113    shm_free(ml);
00114    return NULL;
00115 }
00116 
00117 /**
00118  * free a list
00119  */
00120 void msg_list_free(msg_list ml)
00121 {
00122    msg_list_el p0, p1;
00123 
00124    if(!ml)
00125       return;
00126 
00127    lock_destroy(&ml->sem_sent);
00128    lock_destroy(&ml->sem_done);
00129 
00130    if(ml->nrsent>0 && ml->lsent)
00131    { // free sent list
00132       p0 = ml->lsent;
00133       ml->lsent = NULL;
00134       ml->nrsent = 0;
00135       while(p0)
00136       {
00137          p1 = p0->next;
00138          msg_list_el_free(p0);
00139          p0 = p1;
00140       }     
00141    }
00142 
00143    if(ml->nrdone>0 && ml->ldone)
00144    { // free done list
00145       p0 = ml->ldone;
00146       ml->ldone = NULL;
00147       ml->nrdone = 0;
00148       while(p0)
00149       {
00150          p1 = p0->next;
00151          msg_list_el_free(p0);
00152          p0 = p1;
00153       }
00154    }
00155    
00156    shm_free(ml);  
00157 }
00158 
00159 /**
00160  * check if a message is in list
00161  */
00162 int msg_list_check_msg(msg_list ml, int mid)
00163 {
00164    msg_list_el p0, p1;  
00165    
00166    if(!ml || mid==0)
00167       goto errorx;
00168 
00169    LM_DBG("checking msgid=%d\n", mid);
00170    
00171    lock_get(&ml->sem_sent);
00172 
00173    p0 = p1 = ml->lsent;
00174    while(p0)
00175    {
00176       if(p0->msgid==mid)
00177          goto exist;
00178       p1 = p0;
00179       p0 = p0->next;
00180    }
00181 
00182    p0 = msg_list_el_new();
00183    if(!p0)
00184    {
00185       LM_ERR("failed to create new msg elem.\n");
00186       goto error;
00187    }
00188    p0->msgid = mid;
00189    p0->flag |= MS_MSG_SENT;
00190 
00191    if(p1)
00192    {
00193       p1->next = p0;
00194       p0->prev = p1;
00195       goto done;
00196    }
00197    
00198    ml->lsent = p0;
00199       
00200 done:
00201    ml->nrsent++;
00202    lock_release(&ml->sem_sent);
00203    LM_DBG("msg added to sent list.\n");
00204    return MSG_LIST_OK;
00205 exist:
00206    lock_release(&ml->sem_sent);
00207    LM_DBG("msg already in sent list.\n");
00208    return MSG_LIST_EXIST;  
00209 error:
00210    lock_release(&ml->sem_sent);
00211 errorx:
00212    return MSG_LIST_ERR;
00213 }
00214 
00215 /**
00216  * set flag for message with mid
00217  */
00218 int msg_list_set_flag(msg_list ml, int mid, int fl)
00219 {
00220    msg_list_el p0;   
00221    
00222    if(ml==0 || mid==0)
00223    {
00224       LM_ERR("bad param %p / %d\n", ml, fl);
00225       goto errorx;
00226    }
00227    
00228    lock_get(&ml->sem_sent);
00229 
00230    p0 = ml->lsent;
00231    while(p0)
00232    {
00233       if(p0->msgid==mid)
00234       {
00235          p0->flag |= fl;
00236          LM_DBG("mid:%d fl:%d\n", p0->msgid, fl);
00237          goto done;
00238       }
00239       p0 = p0->next;
00240    }
00241 
00242 done:
00243    lock_release(&ml->sem_sent);
00244    return MSG_LIST_OK;
00245 errorx:
00246    return MSG_LIST_ERR;
00247 }
00248 
00249 /**
00250  * check if the messages from list were sent
00251  */
00252 int msg_list_check(msg_list ml)
00253 {
00254    msg_list_el p0;   
00255    
00256    if(!ml)
00257       goto errorx;
00258    
00259    lock_get(&ml->sem_sent);
00260    if(ml->nrsent<=0)
00261       goto done;
00262    
00263    lock_get(&ml->sem_done);
00264    
00265    p0 = ml->lsent;
00266    while(p0)
00267    {
00268       if(p0->flag & MS_MSG_DONE || p0->flag & MS_MSG_ERRO)
00269       {
00270          LM_DBG("mid:%d got reply\n", p0->msgid);
00271          if(p0->prev)
00272             (p0->prev)->next = p0->next;
00273          else
00274              ml->lsent = p0->next;
00275          if(p0->next)
00276             (p0->next)->prev = p0->prev;
00277          ml->nrsent--;
00278          if(!ml->nrsent)
00279             ml->lsent = NULL;
00280 
00281          if(ml->ldone)
00282             (ml->ldone)->prev = p0;
00283          p0->next = ml->ldone;
00284          
00285          p0->prev = NULL;
00286 
00287          ml->ldone = p0;
00288          ml->nrdone++;
00289       }
00290       p0 = p0->next;
00291    }
00292 
00293    lock_release(&ml->sem_done);
00294 
00295 done:
00296    lock_release(&ml->sem_sent);
00297    return MSG_LIST_OK;
00298 errorx:
00299    return MSG_LIST_ERR;
00300 }
00301 
00302 /**
00303  * reset a list
00304  * return old list
00305  */
00306 msg_list_el msg_list_reset(msg_list ml)
00307 {
00308    msg_list_el p0;   
00309    
00310    if(!ml)
00311       return NULL;
00312    
00313    lock_get(&ml->sem_done);
00314    p0 = ml->ldone;
00315    ml->ldone = NULL;
00316    ml->nrdone = 0;
00317    lock_release(&ml->sem_done);
00318    
00319    return p0;
00320 }
00321 

Generated on Wed May 23 20:00:28 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6