]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/DiskThreads/async_io.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / DiskIO / DiskThreads / async_io.cc
1 /*
2 * Copyright (C) 1996-2019 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 /* DEBUG: section 32 Asynchronous Disk I/O */
10
11 #include "squid.h"
12 #include "DiskThreads.h"
13 #include "DiskThreadsIOStrategy.h"
14 #include "fde.h"
15 #include "Generic.h"
16 #include "Store.h"
17
18 AIOCounts squidaio_counts;
19
20 typedef struct squidaio_unlinkq_t {
21 char *path;
22
23 struct squidaio_unlinkq_t *next;
24 } squidaio_unlinkq_t;
25
26 dlink_list used_list;
27
28 void
29 aioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callback_data)
30 {
31 squidaio_ctrl_t *ctrlp;
32
33 assert(DiskThreadsIOStrategy::Instance.initialised);
34 ++squidaio_counts.open_start;
35 ctrlp = new squidaio_ctrl_t;
36 ctrlp->fd = -2;
37 ctrlp->done_handler = callback;
38 ctrlp->done_handler_data = cbdataReference(callback_data);
39 ctrlp->operation = _AIO_OPEN;
40 ctrlp->result.data = ctrlp;
41 squidaio_open(path, oflag, mode, &ctrlp->result);
42 dlinkAdd(ctrlp, &ctrlp->node, &used_list);
43 return;
44 }
45
46 void
47 aioClose(int fd)
48 {
49 squidaio_ctrl_t *ctrlp;
50
51 assert(DiskThreadsIOStrategy::Instance.initialised);
52 ++squidaio_counts.close_start;
53 aioCancel(fd);
54 ctrlp = new squidaio_ctrl_t;
55 ctrlp->fd = fd;
56 ctrlp->done_handler = NULL;
57 ctrlp->done_handler_data = NULL;
58 ctrlp->operation = _AIO_CLOSE;
59 ctrlp->result.data = ctrlp;
60 squidaio_close(fd, &ctrlp->result);
61 dlinkAdd(ctrlp, &ctrlp->node, &used_list);
62 return;
63 }
64
65 void
66 aioCancel(int fd)
67 {
68 squidaio_ctrl_t *ctrlp;
69 dlink_node *m, *next;
70
71 assert(DiskThreadsIOStrategy::Instance.initialised);
72 ++squidaio_counts.cancel;
73
74 for (m = used_list.head; m; m = next) {
75 next = m->next;
76 ctrlp = (squidaio_ctrl_t *)m->data;
77
78 if (ctrlp->fd != fd)
79 continue;
80
81 squidaio_cancel(&ctrlp->result);
82
83 if (ctrlp->done_handler) {
84 AIOCB *callback = ctrlp->done_handler;
85 void *cbdata;
86 ctrlp->done_handler = NULL;
87 debugs(32, DBG_IMPORTANT, "this be aioCancel. Danger ahead!");
88
89 if (cbdataReferenceValidDone(ctrlp->done_handler_data, &cbdata))
90 callback(fd, cbdata, NULL, -2, -2);
91
92 /* free data if requested to aioWrite() */
93 if (ctrlp->free_func)
94 ctrlp->free_func(ctrlp->bufp);
95
96 /* free temporary read buffer */
97 if (ctrlp->operation == _AIO_READ)
98 squidaio_xfree(ctrlp->bufp, ctrlp->len);
99 }
100
101 dlinkDelete(m, &used_list);
102 delete ctrlp;
103 }
104 }
105
106 void
107 aioWrite(int fd, off_t offset, char *bufp, size_t len, AIOCB * callback, void *callback_data, FREE * free_func)
108 {
109 squidaio_ctrl_t *ctrlp;
110 int seekmode;
111
112 assert(DiskThreadsIOStrategy::Instance.initialised);
113 ++squidaio_counts.write_start;
114 ctrlp = new squidaio_ctrl_t;
115 ctrlp->fd = fd;
116 ctrlp->done_handler = callback;
117 ctrlp->done_handler_data = cbdataReference(callback_data);
118 ctrlp->operation = _AIO_WRITE;
119 ctrlp->bufp = bufp;
120 ctrlp->free_func = free_func;
121
122 if (offset >= 0)
123 seekmode = SEEK_SET;
124 else {
125 seekmode = SEEK_END;
126 offset = 0;
127 }
128
129 ctrlp->result.data = ctrlp;
130 squidaio_write(fd, bufp, len, offset, seekmode, &ctrlp->result);
131 dlinkAdd(ctrlp, &ctrlp->node, &used_list);
132 } /* aioWrite */
133
134 void
135 aioRead(int fd, off_t offset, size_t len, AIOCB * callback, void *callback_data)
136 {
137 squidaio_ctrl_t *ctrlp;
138 int seekmode;
139
140 assert(DiskThreadsIOStrategy::Instance.initialised);
141 ++squidaio_counts.read_start;
142 ctrlp = new squidaio_ctrl_t;
143 ctrlp->fd = fd;
144 ctrlp->done_handler = callback;
145 ctrlp->done_handler_data = cbdataReference(callback_data);
146 ctrlp->operation = _AIO_READ;
147 ctrlp->len = len;
148 ctrlp->bufp = (char *)squidaio_xmalloc(len);
149
150 if (offset >= 0)
151 seekmode = SEEK_SET;
152 else {
153 seekmode = SEEK_CUR;
154 offset = 0;
155 }
156
157 ctrlp->result.data = ctrlp;
158 squidaio_read(fd, ctrlp->bufp, len, offset, seekmode, &ctrlp->result);
159 dlinkAdd(ctrlp, &ctrlp->node, &used_list);
160 return;
161 } /* aioRead */
162
163 void
164
165 aioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data)
166 {
167 squidaio_ctrl_t *ctrlp;
168
169 assert(DiskThreadsIOStrategy::Instance.initialised);
170 ++squidaio_counts.stat_start;
171 ctrlp = new squidaio_ctrl_t;
172 ctrlp->fd = -2;
173 ctrlp->done_handler = callback;
174 ctrlp->done_handler_data = cbdataReference(callback_data);
175 ctrlp->operation = _AIO_STAT;
176 ctrlp->result.data = ctrlp;
177 squidaio_stat(path, sb, &ctrlp->result);
178 dlinkAdd(ctrlp, &ctrlp->node, &used_list);
179 return;
180 } /* aioStat */
181
182 void
183 aioUnlink(const char *path, AIOCB * callback, void *callback_data)
184 {
185 squidaio_ctrl_t *ctrlp;
186 assert(DiskThreadsIOStrategy::Instance.initialised);
187 ++squidaio_counts.unlink_start;
188 ctrlp = new squidaio_ctrl_t;
189 ctrlp->fd = -2;
190 ctrlp->done_handler = callback;
191 ctrlp->done_handler_data = cbdataReference(callback_data);
192 ctrlp->operation = _AIO_UNLINK;
193 ctrlp->result.data = ctrlp;
194 squidaio_unlink(path, &ctrlp->result);
195 dlinkAdd(ctrlp, &ctrlp->node, &used_list);
196 } /* aioUnlink */
197
198 int
199 aioQueueSize(void)
200 {
201 return squidaio_ctrl_t::UseCount();
202 }
203