2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 32 Asynchronous Disk I/O */
12 #include "DiskThreads.h"
13 #include "DiskThreadsIOStrategy.h"
18 AIOCounts squidaio_counts
;
20 typedef struct squidaio_unlinkq_t
{
23 struct squidaio_unlinkq_t
*next
;
29 aioOpen(const char *path
, int oflag
, mode_t mode
, AIOCB
* callback
, void *callback_data
)
31 squidaio_ctrl_t
*ctrlp
;
33 assert(DiskThreadsIOStrategy::Instance
.initialised
);
34 ++squidaio_counts
.open_start
;
35 ctrlp
= new squidaio_ctrl_t
;
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
);
49 squidaio_ctrl_t
*ctrlp
;
51 assert(DiskThreadsIOStrategy::Instance
.initialised
);
52 ++squidaio_counts
.close_start
;
54 ctrlp
= new squidaio_ctrl_t
;
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
);
68 squidaio_ctrl_t
*ctrlp
;
71 assert(DiskThreadsIOStrategy::Instance
.initialised
);
72 ++squidaio_counts
.cancel
;
74 for (m
= used_list
.head
; m
; m
= next
) {
76 ctrlp
= (squidaio_ctrl_t
*)m
->data
;
81 squidaio_cancel(&ctrlp
->result
);
83 if (ctrlp
->done_handler
) {
84 AIOCB
*callback
= ctrlp
->done_handler
;
86 ctrlp
->done_handler
= NULL
;
87 debugs(32, DBG_IMPORTANT
, "this be aioCancel. Danger ahead!");
89 if (cbdataReferenceValidDone(ctrlp
->done_handler_data
, &cbdata
))
90 callback(fd
, cbdata
, NULL
, -2, -2);
92 /* free data if requested to aioWrite() */
94 ctrlp
->free_func(ctrlp
->bufp
);
96 /* free temporary read buffer */
97 if (ctrlp
->operation
== _AIO_READ
)
98 squidaio_xfree(ctrlp
->bufp
, ctrlp
->len
);
101 dlinkDelete(m
, &used_list
);
107 aioWrite(int fd
, off_t offset
, char *bufp
, size_t len
, AIOCB
* callback
, void *callback_data
, FREE
* free_func
)
109 squidaio_ctrl_t
*ctrlp
;
112 assert(DiskThreadsIOStrategy::Instance
.initialised
);
113 ++squidaio_counts
.write_start
;
114 ctrlp
= new squidaio_ctrl_t
;
116 ctrlp
->done_handler
= callback
;
117 ctrlp
->done_handler_data
= cbdataReference(callback_data
);
118 ctrlp
->operation
= _AIO_WRITE
;
120 ctrlp
->free_func
= free_func
;
129 ctrlp
->result
.data
= ctrlp
;
130 squidaio_write(fd
, bufp
, len
, offset
, seekmode
, &ctrlp
->result
);
131 dlinkAdd(ctrlp
, &ctrlp
->node
, &used_list
);
135 aioRead(int fd
, off_t offset
, size_t len
, AIOCB
* callback
, void *callback_data
)
137 squidaio_ctrl_t
*ctrlp
;
140 assert(DiskThreadsIOStrategy::Instance
.initialised
);
141 ++squidaio_counts
.read_start
;
142 ctrlp
= new squidaio_ctrl_t
;
144 ctrlp
->done_handler
= callback
;
145 ctrlp
->done_handler_data
= cbdataReference(callback_data
);
146 ctrlp
->operation
= _AIO_READ
;
148 ctrlp
->bufp
= (char *)squidaio_xmalloc(len
);
157 ctrlp
->result
.data
= ctrlp
;
158 squidaio_read(fd
, ctrlp
->bufp
, len
, offset
, seekmode
, &ctrlp
->result
);
159 dlinkAdd(ctrlp
, &ctrlp
->node
, &used_list
);
165 aioStat(char *path
, struct stat
*sb
, AIOCB
* callback
, void *callback_data
)
167 squidaio_ctrl_t
*ctrlp
;
169 assert(DiskThreadsIOStrategy::Instance
.initialised
);
170 ++squidaio_counts
.stat_start
;
171 ctrlp
= new squidaio_ctrl_t
;
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
);
183 aioUnlink(const char *path
, AIOCB
* callback
, void *callback_data
)
185 squidaio_ctrl_t
*ctrlp
;
186 assert(DiskThreadsIOStrategy::Instance
.initialised
);
187 ++squidaio_counts
.unlink_start
;
188 ctrlp
= new squidaio_ctrl_t
;
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
);
201 return squidaio_ctrl_t::UseCount();