void master_trigger::run_alone(const char* path /* = NULL */, int count /* = 1 */, int interval /* = 1 */) { // 每个进程只能有一个实例在运行 acl_assert(has_called == false); has_called = true; daemon_mode_ = false; #ifdef WIN32 acl_init(); #endif if (interval <= 0) interval = 1; // 初始化配置参数 conf_.load(path); service_pre_jail(NULL, NULL); service_init(NULL, NULL); int i = 0; while (true) { sleep(interval); service_main(NULL, 0, NULL, NULL); if (count > 0 && ++i >= count) break; } service_exit(NULL, NULL); }
void master_udp::read_callback(int, ACL_EVENT*, ACL_VSTREAM *sstream, void*) { service_main(sstream, NULL, NULL); __count++; if (__count_limit > 0 && __count >= __count_limit) __stop = true; }
void master_threads::run_once(ACL_VSTREAM* client) { if (service_on_accept(client) != 0) return; socket_stream* stream = (socket_stream*) client->context; acl_assert(stream); ACL_SOCKET fd = stream->sock_handle(); int timeout = stream->get_rw_timeout(); while (true) { if (ACL_VSTREAM_BFRD_CNT(client) > 0) { // 当函数返回 1 时表示 client 已经被关闭了 if (service_main(client, NULL) == 1) break; continue; } // acl_read_wait 当 timeout 为 -1 时才是完全阻塞 // 等待连接有数据可读,当为 0 时则会立即返回,当 // > 0 时则等待最多指定超时时间 if(acl_read_wait(fd, timeout > 0 ? timeout : -1) == 0) client->sys_read_ready = 1; else if (service_on_timeout(client, NULL) == 0) continue; else { service_on_close(client, NULL); // 删除流对象时会同时关闭套接字 delete stream; break; } // 当函数返回 1 时表示 client 已经被关闭了 if (service_main(client, NULL) == 1) break; } if (__count_limit > 0 && __count >= __count_limit) __stop = true; }
static void client_thread(int event_type acl_unused, void* arg) { ACL_WORKER_ATTR* attr = (ACL_WORKER_ATTR*) arg; ACL_VSTREAM *client = (ACL_VSTREAM*) attr->run_data; time_t last, cost; while (1) { last = time(NULL); if (service_main(client, NULL) < 0) break; cost = time(NULL) - last; if (cost >= 1) printf("%s: >>> time cost = %ld\r\n", __FILE__, cost); } acl_vstream_close(client); }
void master_proc::listen_callback(int, ACL_EVENT*, ACL_VSTREAM *sstream, void*) { ACL_VSTREAM* client = acl_vstream_accept(sstream, NULL, 0); if (client == NULL) { logger_error("accept error %s", last_serror()); __stop = true; } else { service_main(client, NULL, NULL); acl_vstream_close(client); // 因为在 service_main 里不会关闭连接 __count++; if (__count_limit > 0 && __count >= __count_limit) __stop = true; } }
static void service_test(void) { const char *addr = "127.0.0.1:8885"; ACL_VSTREAM *sstream = acl_vstream_listen(addr, 32), *client; int ret; assert(sstream != NULL); acl_xinetd_params_int_table(NULL, var_conf_int_tab); acl_xinetd_params_str_table(NULL, var_conf_str_tab); acl_xinetd_params_bool_table(NULL, var_conf_bool_tab); printf("listen %s ok\n", addr); service_init(NULL); while (1) { client = acl_vstream_accept(sstream, NULL, 0); if (client == NULL) { printf("accept error: %s\n", acl_last_serror()); break; } while (1) { if (acl_readable(ACL_VSTREAM_SOCK(client)) == 0) continue; ret = service_main(client, NULL); if (ret < 0) { acl_vstream_close(client); break; } if (ret > 0) break; } } service_exit(NULL); acl_vstream_close(sstream); }
void master_threads2::run_once(ACL_VSTREAM* client) { if (service_on_accept(client) != 0) { service_on_close(client, NULL); acl_vstream_close(client); return; } socket_stream* stream = (socket_stream*) client->context; acl_assert(stream); ACL_SOCKET fd = stream->sock_handle(); int timeout = stream->get_rw_timeout(); int ret; while (true) { if (ACL_VSTREAM_BFRD_CNT(client) > 0) { // 当函数返回 1 时表示 client 已经被关闭了 if (service_main(client, NULL) == 1) break; continue; } // acl_read_wait 当 timeout 为 -1 时才是完全阻塞 // 等待连接有数据可读,当为 0 时则会立即返回,当 // > 0 时则等待最多指定超时时间 if(acl_read_wait(fd, timeout > 0 ? timeout : -1) == 0) client->read_ready = 1; else if (service_on_timeout(client, NULL) == 0) continue; else { service_on_close(client, NULL); // stream 对象会在 service_on_close 中被删除, // 但在删除时并不会真正关闭套接流,所以需要在 // 此处关闭套接字流 acl_vstream_close(client); break; } // 返回 -1 表示需要关闭该客户端连接 if ((ret = service_main(client, NULL)) == -1) { service_on_close(client, NULL); // stream 对象会在 service_on_close 中被删除, // 但在删除时并不会真正关闭套接流,所以需要在 // 此处关闭套接字流 acl_vstream_close(client); break; } // service_main 只能返回 0 或 -1 acl_assert(ret == 0); } if (__count_limit > 0 && __count >= __count_limit) __stop = true; }
int daemon_main(const char * ident, const daemon_winsvc_options * svc_opts, int (*main_func)(int, char **), int argc, char **argv ) { int rc; #ifdef _DEBUG // Enable Debug heap checks _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) |_CRTDBG_ALLOC_MEM_DF|_CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_LEAK_CHECK_DF); #endif // Check for [status|stop|reload|restart|sigusr1|sigusr2] parameters if ((rc = initd_main(ident, argc, argv)) >= 0) return rc; // Check for [install|remove] parameters if (svc_opts && (rc = svcadm_main(ident, svc_opts, argc, argv)) >= 0) return rc; // Run as service if svc_opts.cmd_opt is given as first(!) argument svc_mode = (svc_opts && argc >= 2 && !strcmp(argv[1], svc_opts->cmd_opt)); if (!svc_mode) { // Daemon: Try to simulate a Unix-like daemon HANDLE rev; BOOL exists; // Create main event to detect process type: // 1. new: parent process => start child and wait for detach() or exit() of child. // 2. exists && signaled: child process => do the real work, signal detach() to parent // 3. exists && !signaled: already running => exit() if (!(rev = create_event(EVT_RUNNING, TRUE/*signaled*/, TRUE, &exists))) return 100; if (!exists && !debugging()) { // Event new => parent process return parent_main(rev); } if (WaitForSingleObject(rev, 0) == WAIT_OBJECT_0) { // Event was signaled => In child process return child_main(rev, main_func, argc, argv); } // Event no longer signaled => Already running! daemon_help(stdout, ident, "already running"); CloseHandle(rev); return 1; } else { // Service: Start service_main() via SCM SERVICE_TABLE_ENTRY service_table[] = { { (char*)svc_opts->svcname, service_main }, { NULL, NULL } }; svc_main_func = main_func; svc_main_argc = argc; svc_main_argv = argv; if (!StartServiceCtrlDispatcher(service_table)) { printf("%s: cannot dispatch service, Error=%ld\n" "Option \"%s\" cannot be used to start %s as a service from console.\n" "Use \"%s install ...\" to install the service\n" "and \"net start %s\" to start it.\n", ident, GetLastError(), svc_opts->cmd_opt, ident, ident, ident); #ifdef _DEBUG if (debugging()) service_main(argc, argv); #endif return 100; } Sleep(1000); ExitThread(0); // Do not redo exit() processing /*NOTREACHED*/ return 0; } }
int main(int argc, char **argv) { int i; char *p; startup_log("main()"); dirsep = '\\'; GetModuleFileName(NULL, cfgdir, sizeof cfgdir); startup_log("cfgdir = '%s'", cfgdir); p = strrchr(cfgdir, dirsep); if (p) *p = '\0'; cfgfile[0] = '\0'; snprcat(cfgfile, sizeof cfgfile, "%s%c%s", cfgdir, dirsep, "mrbig.cfg"); startup_log("cfgfile = '%s'", cfgfile); startup_log("SystemRoot = '%s'", getenv("SystemRoot")); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-c")) { i++; if (argv[i] == NULL) { fprintf(stderr, "No cfg file\n"); return EXIT_FAILURE; } } else if (!strcmp(argv[i], "-d")) { debug++; } else if (!strcmp(argv[i], "-m")) { debug_memory = 1; } else if (!strncmp(argv[i], "-i", 2)) { if (argv[i][2] == '\0') { install_service("MrBig", "Mr Big Monitoring Agent"); } else { install_service(argv[i]+2, argv[i]+2); } return 0; } else if (!strncmp(argv[i], "-u", 2)) { if (argv[i][2] == '\0') { delete_service("MrBig"); } else { delete_service(argv[i]+2); } return 0; } else if (!strcmp(argv[i], "-t")) { standalone = 1; } else { fprintf(stderr, "Bogus option '%s'\n", argv[i]); usage(); } } if (standalone) { mrbig(); return 0; } startup_log("We want to become a service"); service_main(argc, argv); dump_chunks(); check_chunks("just before exit"); dump_files(); return 0; }
int main(int argc, char **argv){ if(argc > 1) return interactive_main(argc,argv); else return service_main(argc,argv); }