2 * Copyright (C) 1996-2016 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"
19 * squidaio_ctrl_t uses explicit alloc()/freeOne() allocators
20 * XXX: convert to MEMPROXY_CLASS() API
24 AIOCounts squidaio_counts
;
26 typedef struct squidaio_unlinkq_t
{
29 struct squidaio_unlinkq_t
*next
;
35 aioOpen(const char *path
, int oflag
, mode_t mode
, AIOCB
* callback
, void *callback_data
)
37 squidaio_ctrl_t
*ctrlp
;
39 assert(DiskThreadsIOStrategy::Instance
.initialised
);
40 ++squidaio_counts
.open_start
;
41 ctrlp
= new squidaio_ctrl_t
;
43 ctrlp
->done_handler
= callback
;
44 ctrlp
->done_handler_data
= cbdataReference(callback_data
);
45 ctrlp
->operation
= _AIO_OPEN
;
46 ctrlp
->result
.data
= ctrlp
;
47 squidaio_open(path
, oflag
, mode
, &ctrlp
->result
);
48 dlinkAdd(ctrlp
, &ctrlp
->node
, &used_list
);
55 squidaio_ctrl_t
*ctrlp
;
57 assert(DiskThreadsIOStrategy::Instance
.initialised
);
58 ++squidaio_counts
.close_start
;
60 ctrlp
= new squidaio_ctrl_t
;
62 ctrlp
->done_handler
= NULL
;
63 ctrlp
->done_handler_data
= NULL
;
64 ctrlp
->operation
= _AIO_CLOSE
;
65 ctrlp
->result
.data
= ctrlp
;
66 squidaio_close(fd
, &ctrlp
->result
);
67 dlinkAdd(ctrlp
, &ctrlp
->node
, &used_list
);
74 squidaio_ctrl_t
*ctrlp
;
77 assert(DiskThreadsIOStrategy::Instance
.initialised
);
78 ++squidaio_counts
.cancel
;
80 for (m
= used_list
.head
; m
; m
= next
) {
82 ctrlp
= (squidaio_ctrl_t
*)m
->data
;
87 squidaio_cancel(&ctrlp
->result
);
89 if (ctrlp
->done_handler
) {
90 AIOCB
*callback
= ctrlp
->done_handler
;
92 ctrlp
->done_handler
= NULL
;
93 debugs(32, DBG_IMPORTANT
, "this be aioCancel. Danger ahead!");
95 if (cbdataReferenceValidDone(ctrlp
->done_handler_data
, &cbdata
))
96 callback(fd
, cbdata
, NULL
, -2, -2);
98 /* free data if requested to aioWrite() */
100 ctrlp
->free_func(ctrlp
->bufp
);
102 /* free temporary read buffer */
103 if (ctrlp
->operation
== _AIO_READ
)
104 squidaio_xfree(ctrlp
->bufp
, ctrlp
->len
);
107 dlinkDelete(m
, &used_list
);
113 aioWrite(int fd
, off_t offset
, char *bufp
, size_t len
, AIOCB
* callback
, void *callback_data
, FREE
* free_func
)
115 squidaio_ctrl_t
*ctrlp
;
118 assert(DiskThreadsIOStrategy::Instance
.initialised
);
119 ++squidaio_counts
.write_start
;
120 ctrlp
= new squidaio_ctrl_t
;
122 ctrlp
->done_handler
= callback
;
123 ctrlp
->done_handler_data
= cbdataReference(callback_data
);
124 ctrlp
->operation
= _AIO_WRITE
;
126 ctrlp
->free_func
= free_func
;
135 ctrlp
->result
.data
= ctrlp
;
136 squidaio_write(fd
, bufp
, len
, offset
, seekmode
, &ctrlp
->result
);
137 dlinkAdd(ctrlp
, &ctrlp
->node
, &used_list
);
141 aioRead(int fd
, off_t offset
, size_t len
, AIOCB
* callback
, void *callback_data
)
143 squidaio_ctrl_t
*ctrlp
;
146 assert(DiskThreadsIOStrategy::Instance
.initialised
);
147 ++squidaio_counts
.read_start
;
148 ctrlp
= new squidaio_ctrl_t
;
150 ctrlp
->done_handler
= callback
;
151 ctrlp
->done_handler_data
= cbdataReference(callback_data
);
152 ctrlp
->operation
= _AIO_READ
;
154 ctrlp
->bufp
= (char *)squidaio_xmalloc(len
);
163 ctrlp
->result
.data
= ctrlp
;
164 squidaio_read(fd
, ctrlp
->bufp
, len
, offset
, seekmode
, &ctrlp
->result
);
165 dlinkAdd(ctrlp
, &ctrlp
->node
, &used_list
);
171 aioStat(char *path
, struct stat
*sb
, AIOCB
* callback
, void *callback_data
)
173 squidaio_ctrl_t
*ctrlp
;
175 assert(DiskThreadsIOStrategy::Instance
.initialised
);
176 ++squidaio_counts
.stat_start
;
177 ctrlp
= new squidaio_ctrl_t
;
179 ctrlp
->done_handler
= callback
;
180 ctrlp
->done_handler_data
= cbdataReference(callback_data
);
181 ctrlp
->operation
= _AIO_STAT
;
182 ctrlp
->result
.data
= ctrlp
;
183 squidaio_stat(path
, sb
, &ctrlp
->result
);
184 dlinkAdd(ctrlp
, &ctrlp
->node
, &used_list
);
189 aioUnlink(const char *path
, AIOCB
* callback
, void *callback_data
)
191 squidaio_ctrl_t
*ctrlp
;
192 assert(DiskThreadsIOStrategy::Instance
.initialised
);
193 ++squidaio_counts
.unlink_start
;
194 ctrlp
= new squidaio_ctrl_t
;
196 ctrlp
->done_handler
= callback
;
197 ctrlp
->done_handler_data
= cbdataReference(callback_data
);
198 ctrlp
->operation
= _AIO_UNLINK
;
199 ctrlp
->result
.data
= ctrlp
;
200 squidaio_unlink(path
, &ctrlp
->result
);
201 dlinkAdd(ctrlp
, &ctrlp
->node
, &used_list
);
207 return squidaio_ctrl_t::UseCount();