source: squid-ssl/trunk/fuentes/src/DiskIO/AIO/AIODiskIOStrategy.cc @ 5495

Last change on this file since 5495 was 5495, checked in by Juanma, 4 years ago

Initial release

File size: 5.1 KB
Line 
1/*
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/*
10 * Author: Adrian Chadd <adrian@squid-cache.org>
11 *
12 * These routines are simple plugin replacements for the file_* routines
13 * in disk.c . They back-end into the POSIX AIO routines to provide
14 * a nice and simple async IO framework for COSS.
15 *
16 * AIO is suitable for COSS - the only sync operations that the standard
17 * supports are read/write, and since COSS works on a single file
18 * per storedir it should work just fine.
19 */
20
21#include "squid.h"
22#include "AIODiskFile.h"
23#include "AIODiskIOStrategy.h"
24#include "DiskIO/IORequestor.h"
25#include "DiskIO/ReadRequest.h"
26#include "DiskIO/WriteRequest.h"
27
28AIODiskIOStrategy::AIODiskIOStrategy() :
29    fd(-1)
30{
31    aq.aq_state = AQ_STATE_NONE;
32    aq.aq_numpending = 0;
33    memset(&aq.aq_queue, 0, sizeof(aq.aq_queue));
34}
35
36AIODiskIOStrategy::~AIODiskIOStrategy()
37{
38    assert(aq.aq_state == AQ_STATE_SETUP ||
39           aq.aq_numpending == 0);
40
41    sync();
42    aq.aq_state = AQ_STATE_NONE;
43}
44
45bool
46AIODiskIOStrategy::shedLoad()
47{
48    return false;
49}
50
51int
52AIODiskIOStrategy::load()
53{
54    return aq.aq_numpending * 1000 / MAX_ASYNCOP;
55}
56
57RefCount<DiskFile>
58AIODiskIOStrategy::newFile (char const *path)
59{
60    if (shedLoad()) {
61        return NULL;
62    }
63
64    return new AIODiskFile (path, this);
65}
66
67void
68AIODiskIOStrategy::sync()
69{
70    assert(aq.aq_state == AQ_STATE_SETUP);
71
72    /*
73     * Keep calling callback to complete ops until the queue is empty
74     * We can't quit when callback returns 0 - some calls may not
75     * return any completed pending events, but they're still pending!
76     */
77
78    while (aq.aq_numpending)
79        callback();
80}
81
82bool
83AIODiskIOStrategy::unlinkdUseful() const
84{
85    return false;
86}
87
88void
89AIODiskIOStrategy::unlinkFile (char const *)
90{}
91
92/*
93 * Note: we grab the state and free the state before calling the callback
94 * because this allows us to cut down the amount of time it'll take
95 * to find a free slot (since if we call the callback first, we're going
96 * to probably be allocated the slot _after_ this one..)
97 *
98 * I'll make it much more optimal later.
99 */
100int
101AIODiskIOStrategy::callback()
102{
103    return 0;
104    int i;
105    int completed = 0;
106    int retval, reterr;
107    FREE *freefunc;
108    void *cbdata;
109    int callback_valid;
110    void *buf;
111    async_queue_entry_t *aqe;
112    async_queue_entry_type_t type;
113
114    assert(aq.aq_state == AQ_STATE_SETUP);
115
116    /* Loop through all slots */
117
118    for (i = 0; i < MAX_ASYNCOP; ++i) {
119        if (aq.aq_queue[i].aq_e_state == AQ_ENTRY_USED) {
120            aqe = &aq.aq_queue[i];
121            /* Active, get status */
122            reterr = aio_error(&aqe->aq_e_aiocb);
123
124            if (reterr < 0) {
125                fatal("aio_error returned an error!\n");
126            }
127
128            if (reterr != EINPROGRESS) {
129                /* Get the return code */
130                retval = aio_return(&aqe->aq_e_aiocb);
131
132                /* Get the callback parameters */
133                freefunc = aqe->aq_e_free;
134                buf = aqe->aq_e_buf;
135                type = aqe->aq_e_type;
136                callback_valid = cbdataReferenceValidDone(aqe->aq_e_callback_data, &cbdata);
137                AIODiskFile * theFile = NULL;
138                void *theFileVoid = NULL;
139                void *theTmpFile = aqe->theFile;
140                bool fileOk = cbdataReferenceValidDone(theTmpFile, &theFileVoid);
141
142                if (fileOk) {
143                    theFile = static_cast<AIODiskFile *>(theFileVoid);
144                }
145
146                /* Free slot */
147                memset(aqe, 0, sizeof(async_queue_entry_t));
148
149                aqe->aq_e_state = AQ_ENTRY_FREE;
150
151                --aq.aq_numpending;
152
153                /* Callback */
154
155                if (callback_valid) {
156                    assert (fileOk);
157
158                    if (type == AQ_ENTRY_READ)
159                        theFile->ioRequestor->readCompleted((const char *)buf, retval, reterr, static_cast<ReadRequest *>(cbdata));
160
161                    if (type == AQ_ENTRY_WRITE)
162                        theFile->ioRequestor->writeCompleted(reterr,retval, static_cast<WriteRequest *>(cbdata));
163                }
164
165                if (type == AQ_ENTRY_WRITE && freefunc)
166                    freefunc(buf);
167            }
168        }
169    }
170
171    return completed;
172}
173
174void
175AIODiskIOStrategy::init()
176{
177    /* Make sure the queue isn't setup */
178    assert(aq.aq_state == AQ_STATE_NONE);
179
180    /* Loop through, blanking the queue entries */
181
182    /* Done */
183    aq.aq_state = AQ_STATE_SETUP;
184}
185
186void
187AIODiskIOStrategy::statfs(StoreEntry & sentry)const
188{}
189
190ConfigOption *
191AIODiskIOStrategy::getOptionTree() const
192{
193    return NULL;
194}
195
196/*
197 * find a free aio slot.
198 * Return the index, or -1 if we can't find one.
199 */
200int
201AIODiskIOStrategy::findSlot()
202{
203    /* Later we should use something a little more .. efficient :) */
204
205    for (int i = 0; i < MAX_ASYNCOP; ++i) {
206        if (aq.aq_queue[i].aq_e_state == AQ_ENTRY_FREE)
207            /* Found! */
208            return i;
209    }
210
211    /* found nothing */
212    return -1;
213}
214
Note: See TracBrowser for help on using the repository browser.