1487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang/*
2487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * Copyright (C) 2016 The Android Open Source Project
3487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang *
4487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * Licensed under the Apache License, Version 2.0 (the "License");
5487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * you may not use this file except in compliance with the License.
6487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * You may obtain a copy of the License at
7487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang *
8487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang *      http://www.apache.org/licenses/LICENSE-2.0
9487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang *
10487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * Unless required by applicable law or agreed to in writing, software
11487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * distributed under the License is distributed on an "AS IS" BASIS,
12487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * See the License for the specific language governing permissions and
14487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * limitations under the License.
15487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang */
16487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
17487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#ifndef _ASYNCIO_H
18487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#define _ASYNCIO_H
19487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
20487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <fcntl.h>
21487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <linux/aio_abi.h>
22487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <memory>
23487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <signal.h>
24487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <sys/cdefs.h>
25487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <sys/types.h>
26487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <time.h>
27487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <thread>
28487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <unistd.h>
29487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
30487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang/**
31487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * Provides a subset of POSIX aio operations, as well
32487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * as similar operations with splice and threadpools.
33487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang */
34487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
35487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangstruct aiocb {
36487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int aio_fildes;     // Assumed to be the source for splices
37487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    void *aio_buf;      // Unused for splices
38487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
39487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    // Used for threadpool operations only, freed automatically
40487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    std::unique_ptr<char[]> aio_pool_buf;
41487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
42487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    off_t aio_offset;
43487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    size_t aio_nbytes;
44487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
45487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int aio_sink;       // Unused for non splice r/w
46487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
47487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    // Used internally
48487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    std::thread thread;
49487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    ssize_t ret;
50487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int error;
517063c936e50326883e672837036381f77080c2f3Jerry Zhang
527063c936e50326883e672837036381f77080c2f3Jerry Zhang    ~aiocb();
53487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang};
54487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
55487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang// Submit a request for IO to be completed
56487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint aio_read(struct aiocb *);
57487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint aio_write(struct aiocb *);
58487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint aio_splice_read(struct aiocb *);
59487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint aio_splice_write(struct aiocb *);
60487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
61487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang// Suspend current thread until given IO is complete, at which point
62487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang// its return value and any errors can be accessed
637063c936e50326883e672837036381f77080c2f3Jerry Zhang// All submitted requests must have a corresponding suspend.
647063c936e50326883e672837036381f77080c2f3Jerry Zhang// aiocb->aio_buf must refer to valid memory until after the suspend call
65487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint aio_suspend(struct aiocb *[], int, const struct timespec *);
66487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint aio_error(const struct aiocb *);
67487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangssize_t aio_return(struct aiocb *);
687063c936e50326883e672837036381f77080c2f3Jerry Zhang
697063c936e50326883e672837036381f77080c2f3Jerry Zhang// (Currently unimplemented)
70487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint aio_cancel(int, struct aiocb *);
71487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
72487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang// Initialize a threadpool to perform IO. Only one pool can be
73487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang// running at a time.
74487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangvoid aio_pool_write_init();
75487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangvoid aio_pool_splice_init();
76487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang// Suspend current thread until all queued work is complete, then ends the threadpool
77487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangvoid aio_pool_end();
78487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang// Submit IO work for the threadpool to complete. Memory associated with the work is
79487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang// freed automatically when the work is complete.
80487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint aio_pool_write(struct aiocb *);
81487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
82487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#endif // ASYNCIO_H
83487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
84