static ChannelServer * channel_server_create(PeerServer * ps, noPollCtx * np_ctx, noPollConn * np_listener, int is_ssl) { ServerNP * si = (ServerNP *)loc_alloc_zero(sizeof *si); /* TODO: need to investigate usage of sizeof(sockaddr_storage) for address buffer size */ si->serv.close = server_close; si->sock = nopoll_conn_socket(np_listener); si->serv.ps = ps; if (server_list.next == NULL) { list_init(&server_list); post_event_with_delay(refresh_all_peer_servers, NULL, PEER_DATA_REFRESH_PERIOD * 1000000); } list_add_last(&si->serv.servlink, &channel_server_root); shutdown_set_normal(&channel_shutdown); list_add_last(&si->servlink, &server_list); refresh_peer_server(si->sock, ps); si->accreq.done = np_server_accept_done; si->accreq.u.user.data = si; si->accreq.u.user.func = np_wt_accept; si->accreq.client_data = si; si->accreq.type = AsyncReqUser; si->np_listener = np_listener; si->np_ctx = np_ctx; si->is_ssl = is_ssl; async_req_post(&si->accreq); return &si->serv; }
static void worker_thread_add(AsyncReqInfo * req) { WorkerThread * wt; assert(is_dispatch_thread()); wt = (WorkerThread *)loc_alloc_zero(sizeof *wt); wt->req = req; check_error(pthread_cond_init(&wt->cond, NULL)); check_error(pthread_create(&wt->thread, &pthread_create_attr, worker_thread_handler, wt)); if (wtrunning_count++ == 0) shutdown_set_normal(&async_shutdown); trace(LOG_ASYNCREQ, "worker_thread_add %p running threads %d", wt, wtrunning_count); }
static ChannelNP * create_channel(noPollConn * np_sock, int en_ssl, int server) { const int i = 1; ChannelNP * c; int sock = nopoll_conn_socket(np_sock); assert(np_sock >= 0); if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&i, sizeof(i)) < 0) { int error = errno; trace(LOG_ALWAYS, "Can't set TCP_NODELAY option on a socket: %s", errno_to_str(error)); errno = error; return NULL; } if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i)) < 0) { int error = errno; trace(LOG_ALWAYS, "Can't set SO_KEEPALIVE option on a socket: %s", errno_to_str(error)); errno = error; return NULL; } c = (ChannelNP *)loc_alloc_zero(sizeof *c); #if ENABLE_Splice if (pipe(c->pipefd) == -1) { int err = errno; loc_free(c); trace(LOG_ALWAYS, "Cannot create channel pipe : %s", errno_to_str(err)); errno = err; return NULL; } #endif /* ENABLE_Splice */ c->magic = CHANNEL_MAGIC; c->is_ssl = en_ssl; c->chan.inp.read = np_read_stream; c->chan.inp.peek = np_peek_stream; c->obuf = output_queue_alloc_obuf(); c->chan.out.cur = c->obuf->buf; c->chan.out.end = c->obuf->buf + sizeof(c->obuf->buf); c->chan.out.write = np_write_stream; c->chan.out.write_block = np_write_block_stream; c->chan.out.splice_block = np_splice_block_stream; list_add_last(&c->chan.chanlink, &channel_root); shutdown_set_normal(&channel_shutdown); c->chan.state = ChannelStateStartWait; c->chan.incoming = server; c->chan.start_comm = start_channel; c->chan.check_pending = channel_check_pending; c->chan.message_count = channel_get_message_count; c->chan.lock = np_lock; c->chan.unlock = np_unlock; c->chan.is_closed = np_is_closed; c->chan.close = send_eof_and_close; ibuf_init(&c->ibuf, &c->chan.inp); c->ibuf.post_read = np_post_read; c->ibuf.wait_read = np_wait_read; c->ibuf.trigger_message = np_trigger_message; c->socket = nopoll_conn_socket(np_sock); c->np_socket = np_sock; c->lock_cnt = 1; c->rd_req.done = np_channel_read_done; c->rd_req.client_data = c; c->rd_req.type = AsyncReqSelect; #if ENABLE_OutputQueue output_queue_ini(&c->out_queue); #endif return c; }