ms_msg_list.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
00059
00060 void msg_list_el_free(msg_list_el mle)
00061 {
00062 if(mle)
00063 shm_free(mle);
00064 }
00065
00066
00067
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
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
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
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 {
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 {
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
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
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
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
00304
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