lw_addr lw_addr_clone (lw_addr ctx) { lw_addr addr = (lw_addr) calloc (sizeof (*addr), 1); if (!addr) return 0; addr->resolver_thread = lw_thread_new ("resolver", (void *) resolver); if (lw_addr_resolve (ctx)) return 0; if (!ctx->info) return 0; addr->info = addr->info_to_free = (struct addrinfo *) malloc (sizeof (*addr->info)); memcpy (addr->info, ctx->info, sizeof (*addr->info)); addr->info->ai_addrlen = ctx->info->ai_addrlen; addr->info->ai_next = 0; addr->info->ai_addr = (struct sockaddr *) malloc (addr->info->ai_addrlen); memcpy (addr->info->ai_addr, ctx->info->ai_addr, addr->info->ai_addrlen); memcpy (addr->service, ctx->service, sizeof (ctx->service)); addr->hostname = addr->hostname_to_free = ctx->hostname; return addr; }
lw_timer lw_timer_new (lw_pump pump) { lw_timer ctx = calloc (sizeof (*ctx), 1); if (!ctx) return 0; ctx->pump = pump; ctx->timer_thread = lw_thread_new ("timer_thread", timer_thread); ctx->stop_event = lw_event_new (); #ifdef _lacewing_use_timerfd ctx->fd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK); lw_pump_add (ctx->pump, ctx->fd, ctx, (lw_pump_callback) timer_tick, 0, lw_true); #endif return ctx; }
void lwp_addr_init (lw_addr ctx, const char * hostname, const char * service, long hints) { char * it; memset (ctx, 0, sizeof (*ctx)); ctx->resolver_thread = lw_thread_new ("resolver", (void *) resolver); ctx->hints = hints; ctx->hostname_to_free = ctx->hostname = strdup (hostname); while (isspace (*ctx->hostname)) ++ ctx->hostname; while (isspace (ctx->hostname [strlen (ctx->hostname) - 1])) ctx->hostname [strlen (ctx->hostname) - 1] = 0; for (it = ctx->hostname; *it; ++ it) { if (it [0] == ':' && it [1] == '/' && it [2] == '/') { *it = 0; service = ctx->hostname; ctx->hostname = it + 3; } if (*it == ':') { /* an explicit port overrides the service name */ service = it + 1; *it = 0; } } lwp_copy_string (ctx->service, service, sizeof (ctx->service)); lw_thread_join (ctx->resolver_thread); /* block if the thread is already running */ lw_thread_start (ctx->resolver_thread, ctx); }