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;
}
示例#2
0
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;
}