#include "lib_acl.h" #include #include #include "service_conf.h" #include "service_main.h" #include "http_module.h" static ACL_AIO *var_aio; static char *var_cfg_event_mode; static char *var_cfg_master_log; static char *var_cfg_listen_addr; static ACL_CONFIG_STR_TABLE __service_conf_str_tab[] = { /* TODO: you can add configure variables of (char *) type here */ /* example: { "mysql_dbaddr", "127.0.0.1:3306", &var_cfg_mysql_dbaddr }, */ { "aio_event_mode", "poll", &var_cfg_event_mode }, { "master_log", "jaws.log", &var_cfg_master_log }, { "master_service", "127.0.0.1:8808", &var_cfg_listen_addr }, { 0, 0, 0 }, }; static int listen_callback(ACL_ASTREAM *sstream, void *context acl_unused) { ACL_SOCKET fd; fd = acl_inet_accept(ACL_VSTREAM_SOCK(acl_aio_vstream(sstream))); if (fd == ACL_SOCKET_INVALID) { printf("accept error(%s)\n", acl_last_serror()); return (-1); } service_main(fd, var_aio); return (0); } static void gc_timer(int event_type acl_unused, void *context) { ACL_AIO *aio = (ACL_AIO *) context; acl_mem_slice_delay_destroy(); } static void run_loop(ACL_AIO *aio, const char *listen_addr) { const char *myname = "run_loop"; ACL_VSTREAM *sstream = acl_vstream_listen(listen_addr, 128); ACL_ASTREAM *astream; if (sstream == NULL) acl_msg_fatal("%s(%d): listen(%s) error(%s)", myname, __LINE__, listen_addr, acl_last_serror()); acl_msg_info("%s(%d): listen %s ok, (fd=%d).", myname, __LINE__, listen_addr, ACL_VSTREAM_SOCK(sstream)); astream = acl_aio_open(aio, sstream); acl_aio_ctl(astream, ACL_AIO_CTL_LISTEN_FN, listen_callback, ACL_AIO_CTL_END); acl_aio_listen(astream); /* 设定定时器定时清理垃圾回收器 */ acl_aio_request_timer(aio, gc_timer, aio, 2, 1); while (1) { acl_aio_loop(aio); } } #ifdef ACL_MS_WINDOWS #include static void onexit_fn(void *arg) { char *procname = (char*) arg; acl_msg_info("%s: exit now", procname); acl_myfree(procname); } static void exec_path(char *exe_path, int size) { char exeFullPath[MAX_PATH]; char szDriver[MAX_PATH]; char szDir[MAX_PATH]; char szFile[MAX_PATH]; char szExt[MAX_PATH]; GetModuleFileName(NULL, exeFullPath, MAX_PATH); _splitpath(exeFullPath, szDriver, szDir, szFile, szExt); _snprintf(exe_path, size, "%s%s", szDriver, szDir); } #endif static void change_path(void) { #ifdef ACL_MS_WINDOWS char path[MAX_PATH]; exec_path(path, sizeof(path)); _chdir(path); #endif } static ACL_FIFO *get_modules(void) { ACL_FIFO *modules = NULL; #ifdef JAWS_STATIC MODULE_SERVICE *module; modules = acl_fifo_new(); module = (MODULE_SERVICE*) acl_mycalloc(1, sizeof(MODULE_SERVICE)); module->mod_init = module_service_init; module->mod_create = module_service_create; module->mod_main = module_service_main; acl_fifo_push(modules, module); #endif return (modules); } static ACL_AIO *init(const char *procname, int use_slice, int open_log acl_unused, const char *conf) { ACL_AIO *aio; int event_mode; ACL_XINETD_CFG_PARSER *cfg; ACL_FIFO *modules; change_path(); if (use_slice) var_mem_slice = acl_mem_slice_init(8, 10240, 100000, ACL_SLICE_FLAG_GC2 | ACL_SLICE_FLAG_RTGC_OFF | ACL_SLICE_FLAG_LP64_ALIGN); else var_mem_slice = NULL; /* 初始化 acl 库 */ acl_init(); /* 加载配置文件 */ cfg = acl_xinetd_cfg_load(conf); if (cfg == NULL) acl_msg_warn("load cfg(%s) error(%s)", conf, acl_last_serror()); acl_xinetd_params_str_table(cfg, service_conf_str_tab); acl_xinetd_params_str_table(cfg, __service_conf_str_tab); acl_xinetd_params_bool_table(cfg, service_conf_bool_tab); acl_xinetd_params_int_table(cfg, service_conf_int_tab); acl_xinetd_cfg_free(cfg); #ifdef ACL_UNIX if (open_log) #endif { acl_msg_open(var_cfg_master_log, "jaws"); } #ifdef ACL_UNIX if (strcasecmp(var_cfg_event_mode, "kernel") == 0) event_mode = ACL_EVENT_KERNEL; else if (strcasecmp(var_cfg_event_mode, "poll") == 0) event_mode = ACL_EVENT_POLL; else #endif event_mode = ACL_EVENT_SELECT; var_aio = aio = acl_aio_create(event_mode); modules = get_modules(); service_init(aio, modules); #ifdef ACL_MS_WINDOWS acl_proctl_child(procname, onexit_fn, acl_mystrdup(procname)); #else (void) procname; #endif return (aio); } static void end(void) { service_exit(); acl_end(); } static void usage(const char *procname) { printf("usage: %s -h[help] -m[use mem slice] -l[open log] -c conf_file\n", procname); } int main(int argc, char *argv[]) { ACL_AIO *aio; char conf[256] = "conf/jaws.cf"; int ch, use_slice = 0, open_log = 0; while ((ch = getopt(argc, argv, "hc:ml")) > 0) { switch (ch) { case 'h': usage(argv[0]); return (0); case 'c': ACL_SAFE_STRNCPY(conf, optarg, sizeof(conf)); break; case 'm': use_slice = 1; break; case 'l': open_log = 1; break; default: break; } } aio = init(argv[0], use_slice, open_log, conf); run_loop(aio, var_cfg_listen_addr); end(); return (0); }