~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/os/unix/ngx_linux_aio_read.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
 
5
 */
 
6
 
 
7
 
 
8
#include <ngx_config.h>
 
9
#include <ngx_core.h>
 
10
#include <ngx_event.h>
 
11
 
 
12
 
 
13
extern int            ngx_eventfd;
 
14
extern aio_context_t  ngx_aio_ctx;
 
15
 
 
16
 
 
17
static void ngx_file_aio_event_handler(ngx_event_t *ev);
 
18
 
 
19
 
 
20
static int
 
21
io_submit(aio_context_t ctx, long n, struct iocb **paiocb)
 
22
{
 
23
    return syscall(SYS_io_submit, ctx, n, paiocb);
 
24
}
 
25
 
 
26
 
 
27
ssize_t
 
28
ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
 
29
    ngx_pool_t *pool)
 
30
{
 
31
    ngx_err_t         err;
 
32
    struct iocb      *piocb[1];
 
33
    ngx_event_t      *ev;
 
34
    ngx_event_aio_t  *aio;
 
35
 
 
36
    if (!ngx_file_aio) {
 
37
        return ngx_read_file(file, buf, size, offset);
 
38
    }
 
39
 
 
40
    aio = file->aio;
 
41
 
 
42
    if (aio == NULL) {
 
43
        aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t));
 
44
        if (aio == NULL) {
 
45
            return NGX_ERROR;
 
46
        }
 
47
 
 
48
        aio->file = file;
 
49
        aio->fd = file->fd;
 
50
        aio->event.data = aio;
 
51
        aio->event.ready = 1;
 
52
        aio->event.log = file->log;
 
53
        file->aio = aio;
 
54
    }
 
55
 
 
56
    ev = &aio->event;
 
57
 
 
58
    if (!ev->ready) {
 
59
        ngx_log_error(NGX_LOG_ALERT, file->log, 0,
 
60
                      "second aio post for \"%V\"", &file->name);
 
61
        return NGX_AGAIN;
 
62
    }
 
63
 
 
64
    ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
 
65
                   "aio complete:%d @%O:%z %V",
 
66
                   ev->complete, offset, size, &file->name);
 
67
 
 
68
    if (ev->complete) {
 
69
        ev->active = 0;
 
70
        ev->complete = 0;
 
71
 
 
72
        if (aio->res >= 0) {
 
73
            ngx_set_errno(0);
 
74
            return aio->res;
 
75
        }
 
76
 
 
77
        ngx_set_errno(-aio->res);
 
78
 
 
79
        ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
 
80
                      "aio read \"%s\" failed", file->name.data);
 
81
 
 
82
        return NGX_ERROR;
 
83
    }
 
84
 
 
85
    ngx_memzero(&aio->aiocb, sizeof(struct iocb));
 
86
 
 
87
    aio->aiocb.aio_data = (uint64_t) (uintptr_t) ev;
 
88
    aio->aiocb.aio_lio_opcode = IOCB_CMD_PREAD;
 
89
    aio->aiocb.aio_fildes = file->fd;
 
90
    aio->aiocb.aio_buf = (uint64_t) (uintptr_t) buf;
 
91
    aio->aiocb.aio_nbytes = size;
 
92
    aio->aiocb.aio_offset = offset;
 
93
    aio->aiocb.aio_flags = IOCB_FLAG_RESFD;
 
94
    aio->aiocb.aio_resfd = ngx_eventfd;
 
95
 
 
96
    ev->handler = ngx_file_aio_event_handler;
 
97
 
 
98
    piocb[0] = &aio->aiocb;
 
99
 
 
100
    if (io_submit(ngx_aio_ctx, 1, piocb) == 1) {
 
101
        ev->active = 1;
 
102
        ev->ready = 0;
 
103
        ev->complete = 0;
 
104
 
 
105
        return NGX_AGAIN;
 
106
    }
 
107
 
 
108
    err = ngx_errno;
 
109
 
 
110
    if (err == NGX_EAGAIN) {
 
111
        return ngx_read_file(file, buf, size, offset);
 
112
    }
 
113
 
 
114
    ngx_log_error(NGX_LOG_CRIT, file->log, err,
 
115
                  "io_submit(\"%V\") failed", &file->name);
 
116
 
 
117
    if (err == NGX_ENOSYS) {
 
118
        ngx_file_aio = 0;
 
119
        return ngx_read_file(file, buf, size, offset);
 
120
    }
 
121
 
 
122
    return NGX_ERROR;
 
123
}
 
124
 
 
125
 
 
126
static void
 
127
ngx_file_aio_event_handler(ngx_event_t *ev)
 
128
{
 
129
    ngx_event_aio_t  *aio;
 
130
 
 
131
    aio = ev->data;
 
132
 
 
133
    ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0,
 
134
                   "aio event handler fd:%d %V", aio->fd, &aio->file->name);
 
135
 
 
136
    aio->handler(ev);
 
137
}