xref: /unit/src/nxt_conn.c (revision 65)
162Sigor@sysoev.ru 
262Sigor@sysoev.ru /*
362Sigor@sysoev.ru  * Copyright (C) Igor Sysoev
462Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
562Sigor@sysoev.ru  */
662Sigor@sysoev.ru 
762Sigor@sysoev.ru #include <nxt_main.h>
862Sigor@sysoev.ru 
962Sigor@sysoev.ru 
1062Sigor@sysoev.ru nxt_conn_io_t  nxt_unix_conn_io = {
1162Sigor@sysoev.ru     nxt_conn_io_connect,
1262Sigor@sysoev.ru     nxt_conn_io_accept,
1362Sigor@sysoev.ru 
1462Sigor@sysoev.ru     nxt_conn_io_read,
1562Sigor@sysoev.ru     nxt_conn_io_recvbuf,
1662Sigor@sysoev.ru     nxt_conn_io_recv,
1762Sigor@sysoev.ru 
1862Sigor@sysoev.ru     nxt_conn_io_write,
1962Sigor@sysoev.ru     nxt_event_conn_io_write_chunk,
2062Sigor@sysoev.ru 
2162Sigor@sysoev.ru #if (NXT_HAVE_LINUX_SENDFILE)
2262Sigor@sysoev.ru     nxt_linux_event_conn_io_sendfile,
2362Sigor@sysoev.ru #elif (NXT_HAVE_FREEBSD_SENDFILE)
2462Sigor@sysoev.ru     nxt_freebsd_event_conn_io_sendfile,
2562Sigor@sysoev.ru #elif (NXT_HAVE_MACOSX_SENDFILE)
2662Sigor@sysoev.ru     nxt_macosx_event_conn_io_sendfile,
2762Sigor@sysoev.ru #elif (NXT_HAVE_SOLARIS_SENDFILEV)
2862Sigor@sysoev.ru     nxt_solaris_event_conn_io_sendfilev,
2962Sigor@sysoev.ru #elif (NXT_HAVE_AIX_SEND_FILE)
3062Sigor@sysoev.ru     nxt_aix_event_conn_io_send_file,
3162Sigor@sysoev.ru #elif (NXT_HAVE_HPUX_SENDFILE)
3262Sigor@sysoev.ru     nxt_hpux_event_conn_io_sendfile,
3362Sigor@sysoev.ru #else
3462Sigor@sysoev.ru     nxt_event_conn_io_sendbuf,
3562Sigor@sysoev.ru #endif
3662Sigor@sysoev.ru 
3762Sigor@sysoev.ru     nxt_event_conn_io_writev,
3862Sigor@sysoev.ru     nxt_event_conn_io_send,
3962Sigor@sysoev.ru 
4062Sigor@sysoev.ru     nxt_conn_io_shutdown,
4162Sigor@sysoev.ru };
4262Sigor@sysoev.ru 
4362Sigor@sysoev.ru 
4462Sigor@sysoev.ru nxt_conn_t *
45*65Sigor@sysoev.ru nxt_conn_create(nxt_mp_t *mp, nxt_task_t *task)
4662Sigor@sysoev.ru {
4762Sigor@sysoev.ru     nxt_conn_t    *c;
4862Sigor@sysoev.ru     nxt_thread_t  *thr;
4962Sigor@sysoev.ru 
50*65Sigor@sysoev.ru     c = nxt_mp_zget(mp, sizeof(nxt_conn_t));
5162Sigor@sysoev.ru     if (nxt_slow_path(c == NULL)) {
5262Sigor@sysoev.ru         return NULL;
5362Sigor@sysoev.ru     }
5462Sigor@sysoev.ru 
5562Sigor@sysoev.ru     c->mem_pool = mp;
5662Sigor@sysoev.ru 
5762Sigor@sysoev.ru     c->socket.fd = -1;
5862Sigor@sysoev.ru 
5962Sigor@sysoev.ru     c->socket.log = &c->log;
6062Sigor@sysoev.ru     c->log = *task->log;
6162Sigor@sysoev.ru 
6262Sigor@sysoev.ru     /* The while loop skips possible uint32_t overflow. */
6362Sigor@sysoev.ru 
6462Sigor@sysoev.ru     while (c->log.ident == 0) {
6562Sigor@sysoev.ru         c->log.ident = nxt_task_next_ident();
6662Sigor@sysoev.ru     }
6762Sigor@sysoev.ru 
6862Sigor@sysoev.ru     thr = nxt_thread();
6962Sigor@sysoev.ru     thr->engine->connections++;
7062Sigor@sysoev.ru 
7162Sigor@sysoev.ru     c->task.thread = thr;
7262Sigor@sysoev.ru     c->task.log = &c->log;
7362Sigor@sysoev.ru     c->task.ident = c->log.ident;
7462Sigor@sysoev.ru     c->socket.task = &c->task;
7562Sigor@sysoev.ru     c->read_timer.task = &c->task;
7662Sigor@sysoev.ru     c->write_timer.task = &c->task;
7762Sigor@sysoev.ru 
7862Sigor@sysoev.ru     c->io = thr->engine->event.io;
7962Sigor@sysoev.ru     c->max_chunk = NXT_INT32_T_MAX;
8062Sigor@sysoev.ru     c->sendfile = NXT_CONN_SENDFILE_UNSET;
8162Sigor@sysoev.ru 
8262Sigor@sysoev.ru     c->socket.read_work_queue = &thr->engine->fast_work_queue;
8362Sigor@sysoev.ru     c->socket.write_work_queue = &thr->engine->fast_work_queue;
8462Sigor@sysoev.ru 
8562Sigor@sysoev.ru     nxt_conn_timer_init(&c->read_timer, c, c->socket.read_work_queue);
8662Sigor@sysoev.ru     nxt_conn_timer_init(&c->write_timer, c, c->socket.write_work_queue);
8762Sigor@sysoev.ru 
8862Sigor@sysoev.ru     nxt_log_debug(&c->log, "connections: %uD", thr->engine->connections);
8962Sigor@sysoev.ru 
9062Sigor@sysoev.ru     return c;
9162Sigor@sysoev.ru }
9262Sigor@sysoev.ru 
9362Sigor@sysoev.ru 
9462Sigor@sysoev.ru void
9562Sigor@sysoev.ru nxt_conn_io_shutdown(nxt_task_t *task, void *obj, void *data)
9662Sigor@sysoev.ru {
9762Sigor@sysoev.ru     int            ret;
9862Sigor@sysoev.ru     socklen_t      len;
9962Sigor@sysoev.ru     nxt_conn_t     *c;
10062Sigor@sysoev.ru     struct linger  linger;
10162Sigor@sysoev.ru 
10262Sigor@sysoev.ru     c = obj;
10362Sigor@sysoev.ru 
10462Sigor@sysoev.ru     nxt_debug(task, "event conn shutdown");
10562Sigor@sysoev.ru 
10662Sigor@sysoev.ru     if (c->socket.timedout) {
10762Sigor@sysoev.ru         /*
10862Sigor@sysoev.ru          * Resetting of timed out connection on close
10962Sigor@sysoev.ru          * releases kernel memory associated with socket.
11062Sigor@sysoev.ru          * This also causes sending TCP/IP RST to a peer.
11162Sigor@sysoev.ru          */
11262Sigor@sysoev.ru         linger.l_onoff = 1;
11362Sigor@sysoev.ru         linger.l_linger = 0;
11462Sigor@sysoev.ru         len = sizeof(struct linger);
11562Sigor@sysoev.ru 
11662Sigor@sysoev.ru         ret = setsockopt(c->socket.fd, SOL_SOCKET, SO_LINGER, &linger, len);
11762Sigor@sysoev.ru 
11862Sigor@sysoev.ru         if (nxt_slow_path(ret != 0)) {
11962Sigor@sysoev.ru             nxt_log(task, NXT_LOG_CRIT, "setsockopt(%d, SO_LINGER) failed %E",
12062Sigor@sysoev.ru                     c->socket.fd, nxt_socket_errno);
12162Sigor@sysoev.ru         }
12262Sigor@sysoev.ru     }
12362Sigor@sysoev.ru 
12462Sigor@sysoev.ru     c->write_state->close_handler(task, c, data);
12562Sigor@sysoev.ru }
12662Sigor@sysoev.ru 
12762Sigor@sysoev.ru 
12862Sigor@sysoev.ru void
12962Sigor@sysoev.ru nxt_conn_timer(nxt_event_engine_t *engine, nxt_conn_t *c,
13062Sigor@sysoev.ru     const nxt_conn_state_t *state, nxt_timer_t *timer)
13162Sigor@sysoev.ru {
13262Sigor@sysoev.ru     nxt_msec_t  value;
13362Sigor@sysoev.ru 
13462Sigor@sysoev.ru     if (state->timer_value != NULL) {
13562Sigor@sysoev.ru         value = state->timer_value(c, state->timer_data);
13662Sigor@sysoev.ru 
13762Sigor@sysoev.ru         if (value != 0) {
13862Sigor@sysoev.ru             timer->handler = state->timer_handler;
13962Sigor@sysoev.ru             nxt_timer_add(engine, timer, value);
14062Sigor@sysoev.ru         }
14162Sigor@sysoev.ru     }
14262Sigor@sysoev.ru }
14362Sigor@sysoev.ru 
14462Sigor@sysoev.ru 
14562Sigor@sysoev.ru void
14662Sigor@sysoev.ru nxt_conn_work_queue_set(nxt_conn_t *c, nxt_work_queue_t *wq)
14762Sigor@sysoev.ru {
14862Sigor@sysoev.ru     c->read_work_queue = wq;
14962Sigor@sysoev.ru     c->write_work_queue = wq;
15062Sigor@sysoev.ru     c->read_timer.work_queue = wq;
15162Sigor@sysoev.ru     c->write_timer.work_queue = wq;
15262Sigor@sysoev.ru }
153