00001
00056 #include "transaction.h"
00057
00058 #include "timer.h"
00059 #include "globals.h"
00060
00061
00062 cdp_trans_list_t *trans_list=0;
00069 int trans_init()
00070 {
00071 trans_list = shm_malloc(sizeof(cdp_trans_list_t));
00072 if (!trans_list){
00073 LOG_NO_MEM("shm",sizeof(cdp_trans_list_t));
00074 return 0;
00075 }
00076 trans_list->head = 0;
00077 trans_list->tail = 0;
00078 trans_list->lock = lock_alloc();
00079 trans_list->lock = lock_init(trans_list->lock);
00080
00081 add_timer(1,0,trans_timer,0);
00082 return 1;
00083 }
00084
00094 inline cdp_trans_t* add_trans(AAAMessage *msg,AAATransactionCallback_f *cb, void *ptr,int timeout,int auto_drop)
00095 {
00096 cdp_trans_t *x;
00097 x = shm_malloc(sizeof(cdp_trans_t));
00098 if (!x) {
00099 LOG_NO_MEM("shm",sizeof(cdp_trans_t));
00100 return 0;
00101 }
00102 x->ptr = shm_malloc(sizeof(void*));
00103 if (!x->ptr) {
00104 LOG_NO_MEM("shm",sizeof(void*));
00105 shm_free(x);
00106 return 0;
00107 }
00108 x->endtoendid = msg->endtoendId;
00109 x->hopbyhopid = msg->hopbyhopId;
00110 x->cb = cb;
00111 *(x->ptr) = ptr;
00112 x->expires = timeout + time(0);
00113 x->auto_drop = auto_drop;
00114 x->next = 0;
00115
00116 lock_get(trans_list->lock);
00117 x->prev = trans_list->tail;
00118 if (trans_list->tail) trans_list->tail->next = x;
00119 trans_list->tail = x;
00120 if (!trans_list->head) trans_list->head = x;
00121 lock_release(trans_list->lock);
00122 return x;
00123 }
00124
00129 inline void del_trans(AAAMessage *msg)
00130 {
00131 cdp_trans_t *x;
00132 lock_get(trans_list->lock);
00133 x = trans_list->head;
00134 while(x&& x->endtoendid!=msg->endtoendId && x->hopbyhopid!=msg->hopbyhopId) x = x->next;
00135 if (x){
00136 if (x->prev) x->prev->next = x->next;
00137 else trans_list->head = x->next;
00138 if (x->next) x->next->prev = x->prev;
00139 else trans_list->tail = x->prev;
00140 free_trans(x);
00141 }
00142 lock_release(trans_list->lock);
00143 }
00144
00150 inline cdp_trans_t* take_trans(AAAMessage *msg)
00151 {
00152 cdp_trans_t *x;
00153 lock_get(trans_list->lock);
00154 x = trans_list->head;
00155 while(x&& x->endtoendid!=msg->endtoendId && x->hopbyhopid!=msg->hopbyhopId) x = x->next;
00156 if (x){
00157 if (x->prev) x->prev->next = x->next;
00158 else trans_list->head = x->next;
00159 if (x->next) x->next->prev = x->prev;
00160 else trans_list->tail = x->prev;
00161 }
00162 lock_release(trans_list->lock);
00163 return x;
00164 }
00165
00170 inline void free_trans(cdp_trans_t *x)
00171 {
00172 if (x->ptr) shm_free(x->ptr);
00173 shm_free(x);
00174 }
00175
00181 void trans_timer(time_t now, void* ptr)
00182 {
00183 cdp_trans_t *x,*n;
00184 LOG(L_DBG,"DBG:trans_timer(): taking care of diameter transactions...\n");
00185 lock_get(trans_list->lock);
00186 x = trans_list->head;
00187 while(x)
00188 {
00189 if (now>x->expires){
00190 x->ans = 0;
00191 if (x->cb){
00192 (x->cb)(1,*(x->ptr),0);
00193 }
00194 n = x->next;
00195
00196 if (x->prev) x->prev->next = x->next;
00197 else trans_list->head = x->next;
00198 if (x->next) x->next->prev = x->prev;
00199 else trans_list->tail = x->prev;
00200 if (x->auto_drop) free_trans(x);
00201
00202 x = n;
00203 } else
00204 x = x->next;
00205 }
00206 lock_release(trans_list->lock);
00207 }
00208