00001
00025 #include <stdio.h>
00026 #include <unistd.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029
00030 #include "../../sr_module.h"
00031 #include "../../dprint.h"
00032 #include "../../ut.h"
00033 #include "../../pvar.h"
00034 #include "../../timer_proc.h"
00035 #include "../../route_struct.h"
00036 #include "../../modules/tm/tm_load.h"
00037
00038 #include "async_sleep.h"
00039
00040 MODULE_VERSION
00041
00042 static int async_workers = 1;
00043
00044 static int mod_init(void);
00045 static int child_init(int);
00046 static void mod_destroy(void);
00047
00048 static int w_async_sleep(struct sip_msg* msg, char* sec, char* str2);
00049 static int fixup_async_sleep(void** param, int param_no);
00050 static int w_async_route(struct sip_msg* msg, char* rt, char* sec);
00051 static int fixup_async_route(void** param, int param_no);
00052
00053
00054 struct tm_binds tmb;
00055
00056
00057 static cmd_export_t cmds[]={
00058 {"async_route", (cmd_function)w_async_route, 2, fixup_async_route,
00059 0, REQUEST_ROUTE|FAILURE_ROUTE},
00060 {"async_sleep", (cmd_function)w_async_sleep, 1, fixup_async_sleep,
00061 0, REQUEST_ROUTE|FAILURE_ROUTE},
00062 {0, 0, 0, 0, 0, 0}
00063 };
00064
00065 static param_export_t params[]={
00066 {"workers", INT_PARAM, &async_workers},
00067 {0, 0, 0}
00068 };
00069
00070 struct module_exports exports = {
00071 "async",
00072 DEFAULT_DLFLAGS,
00073 cmds,
00074 params,
00075 0,
00076 0,
00077 0,
00078 0,
00079 mod_init,
00080 0,
00081 mod_destroy,
00082 child_init
00083 };
00084
00085
00086
00090 static int mod_init(void)
00091 {
00092 if (load_tm_api( &tmb ) == -1)
00093 {
00094 LM_ERR("cannot load the TM-functions\n");
00095 return -1;
00096 }
00097
00098 if(async_init_timer_list()<0) {
00099 LM_ERR("cannot initialize internal structure\n");
00100 return -1;
00101 }
00102
00103 register_dummy_timers(async_workers);
00104
00105 return 0;
00106 }
00107
00111 static int child_init(int rank)
00112 {
00113 if (rank!=PROC_MAIN)
00114 return 0;
00115
00116 if(fork_dummy_timer(PROC_TIMER, "ASYNC MOD TIMER", 1 ,
00117 async_timer_exec, NULL, 1 )<0) {
00118 LM_ERR("failed to register timer routine as process\n");
00119 return -1;
00120 }
00121
00122 return 0;
00123 }
00127 static void mod_destroy(void)
00128 {
00129 async_destroy_timer_list();
00130 }
00131
00132 static int w_async_sleep(struct sip_msg* msg, char* sec, char* str2)
00133 {
00134 int s;
00135 async_param_t *ap;
00136
00137 if(msg==NULL)
00138 return -1;
00139
00140 ap = (async_param_t*)sec;
00141 if(fixup_get_ivalue(msg, ap->pinterval, &s)!=0)
00142 {
00143 LM_ERR("no async sleep time value\n");
00144 return -1;
00145 }
00146 if(ap->type==0)
00147 {
00148 if(ap->u.paction==NULL || ap->u.paction->next==NULL)
00149 {
00150 LM_ERR("cannot be executed as last action in a route block\n");
00151 return -1;
00152 }
00153 if(async_sleep(msg, s, ap->u.paction->next)<0)
00154 return -1;
00155
00156 return 0;
00157 }
00158
00159 return -1;
00160 }
00161
00162 static int fixup_async_sleep(void** param, int param_no)
00163 {
00164 async_param_t *ap;
00165 if(param_no!=1)
00166 return 0;
00167 ap = (async_param_t*)pkg_malloc(sizeof(async_param_t));
00168 if(ap==NULL)
00169 {
00170 LM_ERR("no more pkg\n");
00171 return -1;
00172 }
00173 memset(ap, 0, sizeof(async_param_t));
00174 ap->u.paction = get_action_from_param(param, param_no);
00175 if(fixup_igp_null(param, param_no)<0)
00176 return -1;
00177 ap->pinterval = (gparam_t*)(*param);
00178 *param = (void*)ap;
00179 return 0;
00180 }
00181
00182 static int w_async_route(struct sip_msg* msg, char* rt, char* sec)
00183 {
00184 cfg_action_t *act;
00185 int s;
00186 str rn;
00187 int ri;
00188
00189 if(msg==NULL)
00190 return -1;
00191
00192 if(fixup_get_svalue(msg, (gparam_t*)rt, &rn)!=0)
00193 {
00194 LM_ERR("no async route block name\n");
00195 return -1;
00196 }
00197
00198 if(fixup_get_ivalue(msg, (gparam_t*)sec, &s)!=0)
00199 {
00200 LM_ERR("no async interval value\n");
00201 return -1;
00202 }
00203
00204 ri = route_get(&main_rt, rn.s);
00205 if(ri<0)
00206 {
00207 LM_ERR("unable to find route block [%.*s]\n", rn.len, rn.s);
00208 return -1;
00209 }
00210 act = main_rt.rlist[ri];
00211 if(act==NULL)
00212 {
00213 LM_ERR("empty action lists in route block [%.*s]\n", rn.len, rn.s);
00214 return -1;
00215 }
00216
00217 if(async_sleep(msg, s, act)<0)
00218 return -1;
00219
00220 return 0;
00221 }
00222
00223 static int fixup_async_route(void** param, int param_no)
00224 {
00225 if(param_no==1)
00226 {
00227 if(fixup_spve_null(param, 1)<0)
00228 return -1;
00229 return 0;
00230 } else if(param_no==2) {
00231 if(fixup_igp_null(param, 1)<0)
00232 return -1;
00233 }
00234 return 0;
00235 }