Mercurial > hg > nginx-quic
view src/os/unix/ngx_linux_aio_read.c @ 8384:c61fcdc1b8e3 quic
UDP: extended datagram context.
Sometimes it is required to process datagram properties at higher level (i.e.
QUIC is interested in source address which may change and IP options). The
patch adds ngx_udp_dgram_t structure used to pass packet-related information
in c->udp.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Fri, 02 Apr 2021 18:58:19 +0300 |
parents | f01ab2dbcfdc |
children |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> extern int ngx_eventfd; extern aio_context_t ngx_aio_ctx; static void ngx_file_aio_event_handler(ngx_event_t *ev); static int io_submit(aio_context_t ctx, long n, struct iocb **paiocb) { return syscall(SYS_io_submit, ctx, n, paiocb); } ngx_int_t ngx_file_aio_init(ngx_file_t *file, ngx_pool_t *pool) { ngx_event_aio_t *aio; aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t)); if (aio == NULL) { return NGX_ERROR; } aio->file = file; aio->fd = file->fd; aio->event.data = aio; aio->event.ready = 1; aio->event.log = file->log; file->aio = aio; return NGX_OK; } ssize_t ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset, ngx_pool_t *pool) { ngx_err_t err; struct iocb *piocb[1]; ngx_event_t *ev; ngx_event_aio_t *aio; if (!ngx_file_aio) { return ngx_read_file(file, buf, size, offset); } if (file->aio == NULL && ngx_file_aio_init(file, pool) != NGX_OK) { return NGX_ERROR; } aio = file->aio; ev = &aio->event; if (!ev->ready) { ngx_log_error(NGX_LOG_ALERT, file->log, 0, "second aio post for \"%V\"", &file->name); return NGX_AGAIN; } ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, "aio complete:%d @%O:%uz %V", ev->complete, offset, size, &file->name); if (ev->complete) { ev->active = 0; ev->complete = 0; if (aio->res >= 0) { ngx_set_errno(0); return aio->res; } ngx_set_errno(-aio->res); ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "aio read \"%s\" failed", file->name.data); return NGX_ERROR; } ngx_memzero(&aio->aiocb, sizeof(struct iocb)); aio->aiocb.aio_data = (uint64_t) (uintptr_t) ev; aio->aiocb.aio_lio_opcode = IOCB_CMD_PREAD; aio->aiocb.aio_fildes = file->fd; aio->aiocb.aio_buf = (uint64_t) (uintptr_t) buf; aio->aiocb.aio_nbytes = size; aio->aiocb.aio_offset = offset; aio->aiocb.aio_flags = IOCB_FLAG_RESFD; aio->aiocb.aio_resfd = ngx_eventfd; ev->handler = ngx_file_aio_event_handler; piocb[0] = &aio->aiocb; if (io_submit(ngx_aio_ctx, 1, piocb) == 1) { ev->active = 1; ev->ready = 0; ev->complete = 0; return NGX_AGAIN; } err = ngx_errno; if (err == NGX_EAGAIN) { return ngx_read_file(file, buf, size, offset); } ngx_log_error(NGX_LOG_CRIT, file->log, err, "io_submit(\"%V\") failed", &file->name); if (err == NGX_ENOSYS) { ngx_file_aio = 0; return ngx_read_file(file, buf, size, offset); } return NGX_ERROR; } static void ngx_file_aio_event_handler(ngx_event_t *ev) { ngx_event_aio_t *aio; aio = ev->data; ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0, "aio event handler fd:%d %V", aio->fd, &aio->file->name); aio->handler(ev); }