int uv__stream_try_select(uv_stream_t* stream, int fd) { /* * kqueue doesn't work with some files from /dev mount on osx. * select(2) in separate thread for those fds */ int kq; int ret; struct kevent filter[1]; struct kevent events[1]; struct timespec timeout; uv__stream_select_t* s; kq = kqueue(); if (kq < 0) { fprintf(stderr, "(libuv) Failed to create kqueue (%d)\n", errno); abort(); } EV_SET(&filter[0], fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0); /* Use small timeout, because we only want to capture EINVALs */ timeout.tv_sec = 0; timeout.tv_nsec = 1; ret = kevent(kq, filter, 1, events, 1, &timeout); close(kq); if (ret < 1) return -1; if ((events[0].flags & EV_ERROR_ORIG) == 0 || events[0].data != EINVAL) { return -1; } /* At this point we definitely know that this fd won't work with kqueue */ s = malloc(sizeof(*s)); if (s == NULL) { /* TODO: Return error */ abort(); } if (uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb)) { return -1; } s->async.flags |= UV__HANDLE_INTERNAL; uv__handle_unref((uv_handle_t*) &s->async); if (uv_sem_init(&s->sem, 0)) goto fatal1; if (uv_mutex_init(&s->mutex)) goto fatal2; /* Create fake fd for io watcher */ s->fake_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (s->fake_fd == -1) goto fatal3; if (uv_thread_create(&s->thread, uv__stream_osx_select, stream)) { goto fatal4; } s->stream = stream; stream->select = s; return 0; fatal4: close(s->fake_fd); fatal3: uv_mutex_destroy(&s->mutex); fatal2: uv_sem_destroy(&s->sem); fatal1: uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); free(s); return -1; }
static void destroy_curl_context(curl_context_t *context) { uv_close((uv_handle_t *) &context->poll_handle, curl_close_cb); }
static void after_shutdown(uv_req_t* req, int status) { uv_close(req->handle, on_close); free(req); }
void write_done( uv_write_t *wreq, int status ) { ctx_t *ctx = ( ctx_t *)wreq->data; uv_close( ( uv_handle_t *)wreq->handle, close_done ); //close client free( wreq ); }
static void check_cb(uv_check_t* handle) { ASSERT(check_cb_called == 0); uv_close((uv_handle_t*) &async_handle, NULL); uv_close((uv_handle_t*) &check_handle, NULL); check_cb_called++; }
static void timeout_cb(uv_timer_t* timer, int status) { uv_close((uv_handle_t*)&server, close_cb); uv_close((uv_handle_t*)&client, close_cb); uv_close((uv_handle_t*)&timeout, close_cb); }
static void timer_cb(uv_timer_t* timer) { timer_cb_called++; uv_close((uv_handle_t*) timer, NULL); }
DLLEXPORT void jl_uv_shutdownCallback(uv_shutdown_t* req, int status) { uv_close((uv_handle_t*) req->handle, &jl_uv_closeHandle); free(req); }
void utb_on_shutdown(uv_shutdown_t* req,int status) { uv_close((uv_handle_t*)req->handle,utb_on_close); UTB_PRINTF("free %p",req); free(req); }
extern "C" void rust_uv_hilvl_close(uv_handle_t* handle, crust_close_cb cb) { handle_data* data = (handle_data*)handle->data; data->close_cb = cb; uv_close(handle, native_close_cb); }
static void tiny_timer_cb(uv_timer_t* handle) { ASSERT(handle == &tiny_timer); uv_close((uv_handle_t*) &tiny_timer, NULL); uv_close((uv_handle_t*) &huge_timer1, NULL); uv_close((uv_handle_t*) &huge_timer2, NULL); }
extern "C" void rust_uv_close(uv_handle_t* handle, uv_close_cb cb) { uv_close(handle, cb); }
extern "C" void rust_uv_stop_op_cb(uv_handle_t* op_handle) { uv_close(op_handle, native_close_op_cb); }
static void connect_cb(uv_connect_t* connect_req, int status) { ASSERT(status == UV_ENOENT); connect_cb_called++; uv_close((uv_handle_t*)&prepare_handle, close_cb); uv_close((uv_handle_t*)&pipe_handle, close_cb); }
static void lws_uv_walk_cb(uv_handle_t *handle, void *arg) { if (!uv_is_closing(handle)) uv_close(handle, lws_uv_close_cb); }
static void lwsgs_email_read(struct uv_stream_s *s, ssize_t nread, const uv_buf_t *buf) { struct lws_email *email = (struct lws_email *)s->data; static const short retcodes[] = { 0, /* idle */ 0, /* connecting */ 220, /* connected */ 250, /* helo */ 250, /* from */ 250, /* to */ 354, /* data */ 250, /* body */ 221, /* quit */ }; uv_write_t write_req; uv_buf_t wbuf; int n; if (nread >= 0) email->email_buf[nread] = '\0'; lwsl_notice("%s: %s\n", __func__, buf->base); if (nread == -1) { lwsl_err("%s: failed\n", __func__); return; } n = atoi(buf->base); if (n != retcodes[email->estate]) { lwsl_err("%s: bad response from server\n", __func__); goto close_conn; } switch (email->estate) { case LGSSMTP_CONNECTED: n = sprintf(email->content, "HELO %s\n", email->email_helo); email->estate = LGSSMTP_SENT_HELO; break; case LGSSMTP_SENT_HELO: n = sprintf(email->content, "MAIL FROM: <%s>\n", email->email_from); email->estate = LGSSMTP_SENT_FROM; break; case LGSSMTP_SENT_FROM: n = sprintf(email->content, "RCPT TO: <%s>\n", email->email_to); email->estate = LGSSMTP_SENT_TO; break; case LGSSMTP_SENT_TO: n = sprintf(email->content, "DATA\n"); email->estate = LGSSMTP_SENT_DATA; break; case LGSSMTP_SENT_DATA: if (email->on_get_body(email, email->content, email->max_content_size)) return; n = strlen(email->content); email->estate = LGSSMTP_SENT_BODY; break; case LGSSMTP_SENT_BODY: n = sprintf(email->content, "quit\n"); email->estate = LGSSMTP_SENT_QUIT; break; case LGSSMTP_SENT_QUIT: lwsl_notice("%s: done\n", __func__); email->on_sent(email); email->estate = LGSSMTP_IDLE; goto close_conn; default: return; } puts(email->content); wbuf = uv_buf_init(email->content, n); uv_write(&write_req, s, &wbuf, 1, on_write_end); return; close_conn: uv_close((uv_handle_t *)s, ccb); }
void async_cb(uv_async_t* async, int status) { printf("async_cb\n"); uv_close((uv_handle_t*) async, NULL); }
void ipc_write_cb(uv_write_t* req, int status) { struct ipc_peer_ctx* ctx; ctx = container_of(req, struct ipc_peer_ctx, write_req); uv_close((uv_handle_t*) &ctx->peer_handle, ipc_close_cb); }
void fork_signal_to_child_cb(uv_signal_t* handle, int signum) { fork_signal_cb_called = signum; uv_close((uv_handle_t*)handle, NULL); }
void destroy_http_context(client_context * context) { uv_close((uv_handle_t*) &context->poll_handle, &close_cb); }
static void timer_cb_touch(uv_timer_t* timer) { uv_close((uv_handle_t*)timer, NULL); touch_file("watch_file"); timer_cb_touch_called++; }
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); }
void shut_done( uv_shutdown_t *req, int status ) { ctx_t *ctx = ( ctx_t *)req->data; uv_close( ( uv_handle_t *)&ctx->tcp, free_done ); free( req ); }
static void on_close(uv_handle_t* peer) { free(peer); uv_close((uv_handle_t*)&tcpServer, NULL); }
JL_DLLEXPORT void jl_forceclose_uv(uv_handle_t *handle) { uv_close(handle,&jl_uv_closeHandle); }
void close_handles() { #if !defined(_WIN32) uv_signal_stop(&sigpipe_); uv_close(copy_cast<uv_signal_t*, uv_handle_t*>(&sigpipe_), NULL); #endif }
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; }
void stop() { uv_close((uv_handle_t *)&async, [](uv_handle_t *handle) { delete reinterpret_cast<AsyncQueue *>(handle->data); }); }
static void spawn_on_exit(uv_process_t *req, MVMint64 exit_status, int term_signal) { if (req->data) *(MVMint64 *)req->data = (exit_status << 8) | term_signal; uv_unref((uv_handle_t *)req); uv_close((uv_handle_t *)req, NULL); }
static void timer_cb(uv_timer_t* handle, int status) { uv_timer_stop(handle); uv_close((uv_handle_t*)handle, 0); }