#include "lib_acl.h" #include "service.h" #include "service_conf.h" #include "service_ipc.h" #include "service_main.h" /*----------------------------------------------------------------------------*/ static ACL_FIFO *__service_modules = NULL; static SERVICE *__service = NULL; static module_service_main_fn __service_callback = NULL; static ACL_DLL_ENV __dll_env; ACL_MEM_SLICE *var_mem_slice = NULL; static SERVICE *service_create(ACL_AIO *aio, ACL_FIFO *service_modules, ACL_ARGV *ip_argv) { const char *myname = "service_create"; ACL_FIFO *services; SERVICE *service, *curr_service = NULL; ACL_ITER iter; /* 关闭持续读功能 */ acl_aio_set_keep_read(aio, 0); services = acl_fifo_new(); /* 加载所有的服务模块 */ acl_foreach(iter, service_modules) { MODULE_SERVICE *module = (MODULE_SERVICE*) iter.data; service = module->mod_create(); if (service == NULL) continue; service->aio = aio; service->module = module; service->rw_timeout = 120; service->conn_timeout = 10; service_set_dns(service, aio, var_cfg_dns_list, var_cfg_dns_lookup_timeout, var_cfg_dns_cache_limit, var_cfg_hosts_list); /* 创建连接池缓存对象 */ service->conn_cache = conn_cache_create(aio, var_cfg_server_conn_limit); if (ip_argv) { ACL_ITER iter2; int i = 0; service->bind_ip_list = (char**) acl_mycalloc(ip_argv->argc + 1, sizeof(char*)); service->bind_ip_index = 0; acl_foreach(iter2, ip_argv) { char *ip = (char*) iter2.data; service->bind_ip_list[i++] = acl_mystrdup(ip); } service->bind_ip_list[i] = NULL; } else { service->bind_ip_list = NULL; service->bind_ip_index = -1; } acl_fifo_push(services, service); } if (acl_fifo_size(service_modules) == 0) acl_msg_fatal("%s(%d): no service available", myname, __LINE__); /* 设置协议处理方式 */ acl_foreach(iter, services) { service = (SERVICE*) iter.data; if (strcasecmp(var_cfg_proto_name, service->name) == 0) { curr_service = service; __service_callback = service->module->mod_main; break; } } acl_fifo_free(services, NULL); if (curr_service == NULL) acl_msg_fatal("%s(%d): unknown protocol name(%s)", myname, __LINE__, var_cfg_proto_name); if (__service_callback == NULL) acl_msg_fatal("%s(%d): __service_callback null", myname, __LINE__); return (curr_service); } static void gc_timer(int event_type acl_unused, void *context) { ACL_AIO *aio = (ACL_AIO *) context; acl_mem_slice_delay_destroy(); } void service_init(ACL_AIO *aio, ACL_FIFO *modules) { const char *myname = "service_init"; ACL_ARGV *ip_argv = NULL; ACL_ITER iter; if (var_cfg_bind_ip_list && strcmp(var_cfg_bind_ip_list, "") != 0) { ip_argv = acl_argv_split(var_cfg_bind_ip_list, ",\t "); } if (var_cfg_aio_buf_size > 0) acl_aio_set_rbuf_size(aio, var_cfg_aio_buf_size); memset(&__dll_env, 0, sizeof(ACL_DLL_ENV)); /* __dll_env.logfp = acl_log_fp(); */ __dll_env.mem_slice = var_mem_slice; if (var_mem_slice) { /* 设定定时器定时清理垃圾回收器 */ acl_aio_request_timer(aio, gc_timer, aio, 2, 1); } if (__dll_env.mem_slice) acl_msg_info("%s(%d): use mem_slice", myname, __LINE__); else acl_msg_info("%s(%d): no use mem_slice", myname, __LINE__); if (var_cfg_debug_mem == 1) { acl_memory_debug_start(); acl_memory_debug_stack(1); } else if (var_cfg_debug_mem == 2) { __dll_env.mmd = acl_debug_malloc_init(NULL, "service_log.txt"); } else if (var_cfg_debug_mem == 3) { acl_memory_debug_start(); acl_memory_debug_stack(1); __dll_env.mmd = acl_debug_malloc_init(NULL, "service_log.txt"); } #ifdef JAWS_STATIC if (modules == NULL) acl_msg_fatal("%s(%d): modules null", myname, __LINE__); __service_modules = modules; #else (void) modules; __service_modules = acl_fifo_new(); service_load_all(__service_modules, var_cfg_service_dlnames); #endif /* 初始化所有加载模块 */ acl_foreach(iter, __service_modules) { MODULE_SERVICE *module = (MODULE_SERVICE*) iter.data; module->mod_init(&__dll_env, var_cfg_service_cfgdir); } if (var_cfg_nthreads > 1) { int i, event_mode = acl_aio_event_mode(aio); SERVICE *service; /* 初始化 IPC 通道 */ service_ipc_init(aio, var_cfg_nthreads); for (i = 0; i < var_cfg_nthreads; i++) { ACL_AIO *aio_thr; /* 创建单独运行的线程实例的异步句柄 */ aio_thr = acl_aio_create(event_mode); if (var_cfg_aio_buf_size > 0) acl_aio_set_rbuf_size(aio, var_cfg_aio_buf_size); service = service_create(aio_thr, __service_modules, ip_argv); service_ipc_add_service(service, __service_callback); } } else { __service = service_create(aio, __service_modules, ip_argv); } if (ip_argv) acl_argv_free(ip_argv); /* 内存垃圾回收定时器 */ service_set_gctimer(aio, 10); } void service_exit(void) { const char *myname = "service_exit"; /* XXX: 在使用内存切片方式时,如果卸载动态加载的库会出现 core 文件,奇怪:) */ /* * service_unload_all(); */ acl_msg_info("%s(%d): jaws exit now", myname, __LINE__); } int service_main(ACL_SOCKET fd, ACL_AIO *aio) { if (var_cfg_debug_mem) acl_msg_info("total alloc: %d", acl_mempool_total_allocated()); #ifdef ACL_UNIX acl_close_on_exec(fd, 1); #endif if (var_cfg_nthreads > 1) { /* 多线程模式下,向各个实例线程发送新的连接 */ service_ipc_add(fd); } else { ACL_VSTREAM *vstream; ACL_ASTREAM *astream; /* 在单线程模式下打开异步流 */ vstream = acl_vstream_fdopen(fd, O_RDWR, var_cfg_aio_buf_size, 0, ACL_VSTREAM_TYPE_SOCK); astream = acl_aio_open(aio, vstream); __service_callback(__service, astream); } return (0); }