static void signal_handling_worker(void* context) { enum signal_action action; uv_signal_t signal1a; uv_signal_t signal1b; uv_signal_t signal2; uv_loop_t loop; int r; action = (enum signal_action) (uintptr_t) context; ASSERT(0 == uv_loop_init(&loop)); /* Setup the signal watchers and start them. */ if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { r = uv_signal_init(&loop, &signal1a); ASSERT(r == 0); r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); ASSERT(r == 0); r = uv_signal_init(&loop, &signal1b); ASSERT(r == 0); r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); ASSERT(r == 0); } if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { r = uv_signal_init(&loop, &signal2); ASSERT(r == 0); r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); ASSERT(r == 0); } /* Signal watchers are now set up. */ uv_sem_post(&sem); /* Wait for all signals. The signal callbacks stop the watcher, so uv_run * will return when all signal watchers caught a signal. */ r = uv_run(&loop, UV_RUN_DEFAULT); ASSERT(r == 0); /* Restart the signal watchers. */ if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); ASSERT(r == 0); r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); ASSERT(r == 0); } if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); ASSERT(r == 0); } /* Wait for signals once more. */ uv_sem_post(&sem); r = uv_run(&loop, UV_RUN_DEFAULT); ASSERT(r == 0); /* Close the watchers. */ if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { uv_close((uv_handle_t*) &signal1a, NULL); uv_close((uv_handle_t*) &signal1b, NULL); } if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { uv_close((uv_handle_t*) &signal2, NULL); } /* Wait for the signal watchers to close. */ r = uv_run(&loop, UV_RUN_DEFAULT); ASSERT(r == 0); uv_loop_close(&loop); }
Signal(): handle<uv_signal_t>() { uv_signal_init(uv_default_loop(), get()); }
Signal(loop& l): handle<uv_signal_t>() { uv_signal_init(l.get(), get()); }
extern "C" int rust_uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { return uv_signal_init(loop, handle); }
int main(int argc, char **argv) { int forks = 1; array_t(char*) addr_set; array_init(addr_set); char *keyfile = NULL; const char *config = NULL; char *keyfile_buf = NULL; /* Long options. */ int c = 0, li = 0, ret = 0; struct option opts[] = { {"addr", required_argument, 0, 'a'}, {"config", required_argument, 0, 'c'}, {"keyfile",required_argument, 0, 'k'}, {"forks",required_argument, 0, 'f'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; while ((c = getopt_long(argc, argv, "a:c:f:k:vVh", opts, &li)) != -1) { switch (c) { case 'a': array_push(addr_set, optarg); break; case 'c': config = optarg; break; case 'f': g_interactive = 0; forks = atoi(optarg); if (forks == 0) { kr_log_error("[system] error '-f' requires number, not '%s'\n", optarg); return EXIT_FAILURE; } #if (!defined(UV_VERSION_HEX)) || (!defined(SO_REUSEPORT)) if (forks > 1) { kr_log_error("[system] libuv 1.7+ is required for SO_REUSEPORT support, multiple forks not supported\n"); return EXIT_FAILURE; } #endif break; case 'k': keyfile_buf = malloc(PATH_MAX); assert(keyfile_buf); /* Check if the path is absolute */ if (optarg[0] == '/') { keyfile = strdup(optarg); } else { /* Construct absolute path, the file may not exist */ keyfile = realpath(".", keyfile_buf); if (keyfile) { int len = strlen(keyfile); int namelen = strlen(optarg); if (len + namelen < PATH_MAX - 1) { keyfile[len] = '/'; memcpy(keyfile + len + 1, optarg, namelen + 1); keyfile = strdup(keyfile); /* Duplicate */ } else { keyfile = NULL; /* Invalidate */ } } } free(keyfile_buf); if (!keyfile) { kr_log_error("[system] keyfile '%s': not writeable\n", optarg); return EXIT_FAILURE; } break; case 'v': kr_debug_set(true); break; case 'V': kr_log_info("%s, version %s\n", "Knot DNS Resolver", PACKAGE_VERSION); return EXIT_SUCCESS; case 'h': case '?': help(argc, argv); return EXIT_SUCCESS; default: help(argc, argv); return EXIT_FAILURE; } } /* Switch to rundir. */ if (optind < argc) { const char *rundir = argv[optind]; if (access(rundir, W_OK) != 0) { kr_log_error("[system] rundir '%s': %s\n", rundir, strerror(errno)); return EXIT_FAILURE; } ret = chdir(rundir); if (ret != 0) { kr_log_error("[system] rundir '%s': %s\n", rundir, strerror(errno)); return EXIT_FAILURE; } if(config && access(config, R_OK) != 0) { kr_log_error("[system] rundir '%s'\n", rundir); kr_log_error("[system] config '%s': %s\n", config, strerror(errno)); return EXIT_FAILURE; } } kr_crypto_init(); /* Fork subprocesses if requested */ int fork_count = forks; while (--forks > 0) { int pid = fork(); if (pid < 0) { perror("[system] fork"); return EXIT_FAILURE; } /* Forked process */ if (pid == 0) { kr_crypto_reinit(); break; } } /* Block signals. */ uv_loop_t *loop = uv_default_loop(); uv_signal_t sigint, sigterm; uv_signal_init(loop, &sigint); uv_signal_init(loop, &sigterm); uv_signal_start(&sigint, signal_handler, SIGINT); uv_signal_start(&sigterm, signal_handler, SIGTERM); /* Create a server engine. */ knot_mm_t pool = { .ctx = mp_new (4096), .alloc = (knot_mm_alloc_t) mp_alloc }; struct engine engine; ret = engine_init(&engine, &pool); if (ret != 0) { kr_log_error("[system] failed to initialize engine: %s\n", kr_strerror(ret)); return EXIT_FAILURE; } /* Create worker */ struct worker_ctx *worker = init_worker(loop, &engine, &pool, forks, fork_count); if (!worker) { kr_log_error("[system] not enough memory\n"); return EXIT_FAILURE; } /* Bind to sockets and run */ for (size_t i = 0; i < addr_set.len; ++i) { int port = 53; const char *addr = set_addr(addr_set.at[i], &port); ret = network_listen(&engine.net, addr, (uint16_t)port, NET_UDP|NET_TCP); if (ret != 0) { kr_log_error("[system] bind to '%s#%d' %s\n", addr, port, knot_strerror(ret)); ret = EXIT_FAILURE; } } /* Start the scripting engine */ if (ret == 0) { ret = engine_start(&engine, config ? config : "config"); if (ret == 0) { if (keyfile) { auto_free char *cmd = afmt("trust_anchors.file = '%s'", keyfile); if (!cmd) { kr_log_error("[system] not enough memory\n"); return EXIT_FAILURE; } engine_cmd(&engine, cmd); lua_settop(engine.L, 0); } /* Run the event loop */ ret = run_worker(loop, &engine); } } /* Cleanup. */ array_clear(addr_set); engine_deinit(&engine); worker_reclaim(worker); mp_delete(pool.ctx); if (ret != 0) { ret = EXIT_FAILURE; } kr_crypto_cleanup(); return ret; }
bud_error_t bud_worker(bud_config_t* config) { int r; bud_error_t err; bud_log(config, kBudLogDebug, "worker starting"); config->loop = uv_default_loop(); config->ipc = malloc(sizeof(*config->ipc)); config->signal.sighup = malloc(sizeof(*config->signal.sighup)); if (config->ipc == NULL || config->signal.sighup == NULL) { err = bud_error_str(kBudErrNoMem, "config->ipc"); goto fatal; } config->ipc->data = config; config->signal.sighup->data = config; r = uv_pipe_init(config->loop, config->ipc, 1); if (r != 0) { err = bud_error_num(kBudErrIPCPipeInit, r); goto fatal; } r = uv_pipe_open(config->ipc, 0); if (r != 0) { err = bud_error_num(kBudErrIPCPipeOpen, r); goto failed_pipe_open; } r = uv_read_start((uv_stream_t*) config->ipc, bud_worker_alloc_cb, bud_worker_read_cb); if (r != 0) { err = bud_error_num(kBudErrIPCReadStart, r); goto failed_pipe_open; } #ifndef _WIN32 /* Drop privileges */ err = bud_config_drop_privileges(config); if (!bud_is_ok(err)) goto failed_pipe_open; r = uv_signal_init(config->loop, config->signal.sighup); if (r != 0) { err = bud_error_num(kBudErrSignalInit, r); goto failed_pipe_open; } r = uv_signal_start(config->signal.sighup, bud_worker_signal_cb, SIGHUP); if (r != 0) { err = bud_error_num(kBudErrSignalInit, r); goto failed_signal_start; } #endif /* !_WIN32 */ err = bud_ok(); return err; #ifndef _WIN32 failed_signal_start: uv_close((uv_handle_t*) config->signal.sighup, bud_worker_close_cb); #endif /* !_WIN32 */ failed_pipe_open: uv_close((uv_handle_t*) config->ipc, bud_worker_close_cb); goto cleanup; fatal: free(config->ipc); cleanup: config->ipc = NULL; return err; }
int uv_loop_init(uv_loop_t* loop) { void* saved_data; int err; saved_data = loop->data; memset(loop, 0, sizeof(*loop)); loop->data = saved_data; heap_init((struct heap*) &loop->timer_heap); QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->idle_handles); QUEUE_INIT(&loop->async_handles); QUEUE_INIT(&loop->check_handles); QUEUE_INIT(&loop->prepare_handles); QUEUE_INIT(&loop->handle_queue); loop->active_handles = 0; loop->active_reqs.count = 0; loop->nfds = 0; loop->watchers = NULL; loop->nwatchers = 0; QUEUE_INIT(&loop->pending_queue); QUEUE_INIT(&loop->watcher_queue); loop->closing_handles = NULL; uv__update_time(loop); loop->async_io_watcher.fd = -1; loop->async_wfd = -1; loop->signal_pipefd[0] = -1; loop->signal_pipefd[1] = -1; loop->backend_fd = -1; loop->emfile_fd = -1; loop->timer_counter = 0; loop->stop_flag = 0; err = uv__platform_loop_init(loop); if (err) return err; uv__signal_global_once_init(); err = uv_signal_init(loop, &loop->child_watcher); if (err) goto fail_signal_init; uv__handle_unref(&loop->child_watcher); loop->child_watcher.flags |= UV_HANDLE_INTERNAL; QUEUE_INIT(&loop->process_handles); err = uv_rwlock_init(&loop->cloexec_lock); if (err) goto fail_rwlock_init; err = uv_mutex_init(&loop->wq_mutex); if (err) goto fail_mutex_init; err = uv_async_init(loop, &loop->wq_async, uv__work_done); if (err) goto fail_async_init; uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV_HANDLE_INTERNAL; return 0; fail_async_init: uv_mutex_destroy(&loop->wq_mutex); fail_mutex_init: uv_rwlock_destroy(&loop->cloexec_lock); fail_rwlock_init: uv__signal_loop_cleanup(loop); fail_signal_init: uv__platform_loop_delete(loop); return err; }
LWS_VISIBLE int lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi) { struct lws_context_per_thread *pt = &context->pt[tsi]; struct lws_vhost *vh = context->vhost_list; int status = 0, n, ns, first = 1; if (!pt->io_loop_uv) { if (!loop) { loop = lws_malloc(sizeof(*loop)); if (!loop) { lwsl_err("OOM\n"); return -1; } #if UV_VERSION_MAJOR > 0 uv_loop_init(loop); #else lwsl_err("This libuv is too old to work...\n"); return 1; #endif pt->ev_loop_foreign = 0; } else { lwsl_notice(" Using foreign event loop...\n"); pt->ev_loop_foreign = 1; } pt->io_loop_uv = loop; uv_idle_init(loop, &pt->uv_idle); ns = ARRAY_SIZE(sigs); if (lws_check_opt(context->options, LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN)) ns = 2; if (pt->context->use_ev_sigint) { assert(ns <= ARRAY_SIZE(pt->signals)); for (n = 0; n < ns; n++) { uv_signal_init(loop, &pt->signals[n]); pt->signals[n].data = pt->context; uv_signal_start(&pt->signals[n], context->lws_uv_sigint_cb, sigs[n]); } } } else first = 0; /* * Initialize the accept wsi read watcher with all the listening sockets * and register a callback for read operations * * We have to do it here because the uv loop(s) are not * initialized until after context creation. */ while (vh) { if (lws_uv_initvhost(vh, vh->lserv_wsi) == -1) return -1; vh = vh->vhost_next; } if (first) { uv_timer_init(pt->io_loop_uv, &pt->uv_timeout_watcher); uv_timer_start(&pt->uv_timeout_watcher, lws_uv_timeout_cb, 10, 1000); } return status; }
int main (int ac, char *av[]) { int ret, ch; char *logfile = NULL; int i, ok; char *tmp, *ptr; uv_signal_t *sigint; uv_signal_t *sigterm; char *pidfile = NULL; struct destination *destination = NULL; struct listener *listener; struct rlimit rl; rl.rlim_cur = 65535; rl.rlim_max = 65535; setrlimit (RLIMIT_NOFILE, &rl); rl.rlim_cur = RLIM_INFINITY; rl.rlim_max = RLIM_INFINITY; setrlimit (RLIMIT_CORE, &rl); signal (SIGPIPE, SIG_IGN); char *mysqltype = NULL; setenv ("TZ", ":/etc/localtime", 0); tzset (); memset (logstring, '\0', sizeof (logstring)); for (i = 0; i < ac; i++) { if (strlen (logstring) + strlen (av[i]) >= sizeof (logstring)) { break; } strcat (logstring, av[i]); if (i != ac - 1) { strcat (logstring, " "); } } pool = malloc (sizeof (*pool)); bufpool_init (pool, BUF_SIZE); /* uv_timer_t *handle; handle = malloc (sizeof(uv_timer_t)); uv_timer_init(uv_default_loop(),handle); uv_timer_start(handle, bufpool_print_stats, 1000, 1000); */ sigint = malloc (sizeof (uv_signal_t)); sigterm = malloc (sizeof (uv_signal_t)); uv_signal_init (uv_default_loop (), sigint); uv_signal_init (uv_default_loop (), sigterm); uv_signal_start (sigint, signal_handler, SIGINT); uv_signal_start (sigterm, signal_handler, SIGTERM); openlog ("rum", LOG_NDELAY | LOG_PID, LOG_DAEMON); if (ac == 1) { usage (); } /* destination is global variable a pointer to struct destination * struct destination forms a linked list * first_destination is pointer to first struct * * struct listener is the same */ listener = NULL; int option_index = 0; static struct option long_options[] = { {"background", no_argument, 0, 'b'}, {"destination", required_argument, 0, 'd'}, {"source", required_argument, 0, 's'}, {"stats", required_argument, 0, 'm'}, {"logfile", required_argument, 0, 'l'}, {"mysql-cdb", required_argument, 0, 'M'}, {"postgresql-cdb", required_argument, 0, 'P'}, {"mysqltype", required_argument, 0, 't'}, {"failover-r", required_argument, 0, 'R'}, {"failover", required_argument, 0, 'f'}, {"read-timeout", required_argument, 0, 0}, {"connect-timeout", required_argument, 0, 0}, {"pidfile", required_argument, 0, 'p'}, {"loglogins", no_argument, 0, 'L'}, {0, 0, 0, 0} }; while ((ch = getopt_long (ac, av, "bd:s:m:l:M:P:t:r:f:R:p:L", long_options, &option_index)) != -1) { switch (ch) { case 0: if (strcmp (long_options[option_index].name, "read-timeout") == 0) read_timeout = atoi (optarg); if (strcmp (long_options[option_index].name, "connect-timeout") == 0) connect_timeout = atoi (optarg); break; case 'b': daemonize = 1; break; case 's': case 'm': if (listener == NULL) { first_listener = listener = malloc (sizeof (struct listener)); } else { listener->next = malloc (sizeof (struct listener)); listener = listener->next; } listener->s = strdup (optarg); listener->stream = NULL; listener->next = NULL; /* vynulujeme statistiky */ listener->nr_conn = 0; listener->nr_allconn = 0; listener->input_bytes = 0; listener->output_bytes = 0; if (ch == 's') { listener->type = LISTENER_DEFAULT; } else if (ch == 'm') { listener->type = LISTENER_STATS; } break; case 'M': /* enable mysql module */ mysql_cdb_file = strdup (optarg); break; case 'P': /* enable mysql module */ postgresql_cdb_file = strdup (optarg); break; case 'd': first_destination = destination = malloc (sizeof (struct destination)); prepare_upstream (optarg, destination); break; case 'l': logfile = strdup (optarg); break; case 'L': loglogins = 1; break; case 't': mysqltype = optarg; break; case 'f': mode = MODE_FAILOVER; ptr = tmp = strdup (optarg); i = 0; while (tmp[i] != '\0') { if (tmp[i] == ',') { tmp[i] = '\0'; add_destination (ptr); destinations++; ptr = tmp + i + 1; } i++; } add_destination (ptr); destinations++; break; case 'R': mode = MODE_FAILOVER_R; ptr = tmp = strdup (optarg); i = 0; while (tmp[i] != '\0') { if (tmp[i] == ',') { tmp[i] = '\0'; add_destination (ptr); destinations++; ptr = tmp + i + 1; } i++; } add_destination (ptr); destinations++; randomize_destinations (); break; case 'p': pidfile = strdup (optarg); break; } } /* if mysql module is enabled, open cdb file and create EV_SIGNAL event which call repoen_cdb(). * if someone send SIGUSR1 cdb file is reopened, but this is automatically triggered by timeout with * CDB_RELOAD_TIME seconds (default 2s) * * reopen_cdb is called from main event loop, it is not called directly by signal, * so it is race condition free (safe to free and init global cdb variable) */ if (mysql_cdb_file) { init_mysql_cdb_file (mysqltype); } if (postgresql_cdb_file) { init_postgresql_cdb_file (mysqltype); } if (daemonize) { if (logfile) { if (daemon (0, 1) < 0) { perror ("daemon()"); exit (0); } close (0); close (1); close (2); ret = open (logfile, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); if (ret != -1) { dup2 (ret, 1); dup2 (ret, 2); } } else { if (daemon (0, 0) < 0) { perror ("daemon()"); exit (0); } } } /* add all listen (-s -m) ports to event_base, if someone connect: accept_connect is executed with struct listener argument */ for (listener = first_listener; listener; listener = listener->next) { for (i = 0, ok = 0; i < 10; i++) { listener->stream = create_listen_socket (listener->s); listener->stream->data = listener; int r = uv_listen ((uv_stream_t *) listener->stream, -1, on_incoming_connection); if (r) { logmsg ("listen to %s failed, retrying", listener->s); uv_close ((uv_handle_t *) listener->stream, on_close_listener); usleep (200 * 1000); } else { logmsg ("listening on %s", listener->s); ok = 1; break; } } if (ok == 0) { logmsg ("listen to %s failed, exiting", listener->s); _exit (-1); } } if (!first_destination && !mysql_cdb_file && !postgresql_cdb_file) { usage (); } if (daemonize) { if (pidfile) { FILE *fp = fopen(pidfile, "w"); if (fp) { fprintf (fp, "%d", getpid()); fclose (fp); } else { logmsg("cannot open pidfile %s (%s)", pidfile, strerror (errno)); } } } /* main libuv loop */ uv_run (uv_default_loop (), UV_RUN_DEFAULT); /* SIGINT || SIGTERM received, clean up */ bufpool_done (pool); free (pool); if (mysql_cdb_file) { free (mysql_cdb_file); } if (postgresql_cdb_file) { free (postgresql_cdb_file); } struct destination *dst; dst = first_destination; while (dst) { destination = dst->next; free (dst->s); free (dst); dst = destination; } free (sigint); free (sigterm); exit (0); }
Signal(Loop& uvloop) { uv_signal_init(uvloop, phandle()); }
int main(int argc, char* argv[]) { char* ipaddr = "0.0.0.0"; int port = 7000; int i; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-a")) { if (i == argc-1) usage(argv[0]); ipaddr = argv[++i]; } else if (!strcmp(argv[i], "-p")) { if (i == argc-1) usage(argv[0]); char* e = NULL; port = strtol(argv[++i], &e, 10); if ((e && *e) || port < 0 || port > 65535) usage(argv[0]); } else if (!strcmp(argv[i], "-d")) { if (i == argc-1) usage(argv[0]); static_dir = argv[++i]; } else usage(argv[0]); } static_dir_len = strlen(static_dir); struct sockaddr_in addr; int r; mime_type = kh_init(mime_type); add_mime_type(".jpg", "image/jpeg"); add_mime_type(".png", "image/png"); add_mime_type(".gif", "image/gif"); add_mime_type(".html", "text/html"); add_mime_type(".txt", "text/plain"); r = uv_ip4_addr(ipaddr, port, &addr); if (r) { fprintf(stderr, "Address error: %s: %s\n", uv_err_name(r), uv_strerror(r)); return 1; } loop = uv_default_loop(); uv_tcp_t server; r = uv_tcp_init(loop, &server); if (r) { fprintf(stderr, "Socket creation error: %s: %s\n", uv_err_name(r), uv_strerror(r)); return 1; } r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); if (r) { fprintf(stderr, "Bind error: %s: %s\n", uv_err_name(r), uv_strerror(r)); return 1; } r = uv_tcp_simultaneous_accepts((uv_tcp_t*) &server, 1); if (r) { fprintf(stderr, "Accept error: %s: %s\n", uv_err_name(r), uv_strerror(r)); return 1; } fprintf(stderr, "Listening %s:%d\n", ipaddr, port); r = uv_listen((uv_stream_t*)&server, SOMAXCONN, on_connection); if (r) { fprintf(stderr, "Listen error: %s: %s\n", uv_err_name(r), uv_strerror(r)); return 1; } uv_signal_t sig; r = uv_signal_init(loop, &sig); if (r) { fprintf(stderr, "Signal error: %s: %s\n", uv_err_name(r), uv_strerror(r)); return 1; } sig.data = loop; r = uv_signal_start(&sig, on_signal, SIGINT); if (r) { fprintf(stderr, "Signal error: %s: %s\n", uv_err_name(r), uv_strerror(r)); return 1; } return uv_run(loop, UV_RUN_DEFAULT); }
LWS_VISIBLE int lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi) { struct lws_context_per_thread *pt = &context->pt[tsi]; struct lws_vhost *vh = context->vhost_list; int status = 0, n; if (!loop) { loop = lws_malloc(sizeof(*loop)); #if UV_VERSION_MAJOR > 0 uv_loop_init(loop); #else lwsl_err("This libuv is too old to work...\n"); return 1; #endif pt->ev_loop_foreign = 0; } else { lwsl_notice(" Using foreign event loop...\n"); pt->ev_loop_foreign = 1; } pt->io_loop_uv = loop; uv_idle_init(loop, &pt->uv_idle); if (pt->context->use_ev_sigint) { assert(ARRAY_SIZE(sigs) <= ARRAY_SIZE(pt->signals)); for (n = 0; n < ARRAY_SIZE(sigs); n++) { uv_signal_init(loop, &pt->signals[n]); pt->signals[n].data = pt->context; uv_signal_start(&pt->signals[n], context->lws_uv_sigint_cb, sigs[n]); } } /* * Initialize the accept wsi read watcher with all the listening sockets * and register a callback for read operations * * We have to do it here because the uv loop(s) are not * initialized until after context creation. */ while (vh) { if (vh->lserv_wsi) { vh->lserv_wsi->w_read.context = context; n = uv_poll_init_socket(pt->io_loop_uv, &vh->lserv_wsi->w_read.uv_watcher, vh->lserv_wsi->sock); if (n) { lwsl_err("uv_poll_init failed %d, sockfd=%p\n", n, (void *)(long)vh->lserv_wsi->sock); return -1; } lws_libuv_io(vh->lserv_wsi, LWS_EV_START | LWS_EV_READ); } vh = vh->vhost_next; } uv_timer_init(pt->io_loop_uv, &pt->uv_timeout_watcher); uv_timer_start(&pt->uv_timeout_watcher, lws_uv_timeout_cb, 1000, 1000); return status; }