async_mod.c

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 /* tm */
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, /* dlopen flags */
00073         cmds,
00074         params,
00075         0,
00076         0,              /* exported MI functions */
00077         0,              /* exported pseudo-variables */
00078         0,              /* extra processes */
00079         mod_init,       /* module initialization function */
00080         0,              /* response function */
00081         mod_destroy,    /* destroy function */
00082         child_init      /* per child init function */
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 /*socks flag*/,
00117                                 async_timer_exec, NULL, 1 /*sec*/)<0) {
00118                 LM_ERR("failed to register timer routine as process\n");
00119                 return -1; /* error */
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                 /* force exit in config */
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         /* force exit in config */
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 }