507 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			507 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /*
 | ||
|  |  * Copyright (c) 2006-2021, RT-Thread Development Team | ||
|  |  * | ||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||
|  |  * | ||
|  |  * Change Logs: | ||
|  |  * Date           Author            Notes | ||
|  |  * 2017/12/30     Bernard           The first version. | ||
|  |  * 2024/03/26     TroyMitchelle     Added some function comments | ||
|  |  * 2024/03/27     TroyMitchelle     Fix the issue of incorrect return of invalid parameters in aio_write | ||
|  |  */ | ||
|  | 
 | ||
|  | #include <rtthread.h>
 | ||
|  | #include <rthw.h>
 | ||
|  | #include <stdint.h>
 | ||
|  | #include <unistd.h>
 | ||
|  | #include <fcntl.h>
 | ||
|  | #include <sys/errno.h>
 | ||
|  | #include "aio.h"
 | ||
|  | 
 | ||
|  | struct rt_workqueue* aio_queue = NULL; | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * The aio_cancel() function shall attempt to cancel one or more asynchronous I/O | ||
|  |  * requests currently outstanding against file descriptor fildes. The aiocbp | ||
|  |  * argument points to the asynchronous I/O control block for a particular request | ||
|  |  * to be canceled. If aiocbp is NULL, then all outstanding cancelable asynchronous | ||
|  |  * I/O requests against fildes shall be canceled. | ||
|  |  * | ||
|  |  * Normal asynchronous notification shall occur for asynchronous I/O operations | ||
|  |  * that are successfully canceled. If there are requests that cannot be canceled, | ||
|  |  * then the normal asynchronous completion process shall take place for those | ||
|  |  * requests when they are completed. | ||
|  |  * | ||
|  |  * For requested operations that are successfully canceled, the associated error | ||
|  |  * status shall be set to [ECANCELED] and the return status shall be -1. For | ||
|  |  * requested operations that are not successfully canceled, the aiocbp shall not | ||
|  |  * be modified by aio_cancel(). | ||
|  |  * | ||
|  |  * If aiocbp is not NULL, then if fildes does not have the same value as the file | ||
|  |  * descriptor with which the asynchronous operation was initiated, unspecified results occur. | ||
|  |  * | ||
|  |  * Which operations are cancelable is implementation-defined. | ||
|  |  */ | ||
|  | int aio_cancel(int fd, struct aiocb *cb) | ||
|  | { | ||
|  |     rt_err_t ret; | ||
|  | 
 | ||
|  |     if (!cb) return -EINVAL; | ||
|  |     if (cb->aio_fildes != fd) return -EINVAL; | ||
|  | 
 | ||
|  |     ret = rt_workqueue_cancel_work_sync(aio_queue, &(cb->aio_work)); | ||
|  |     if (ret == RT_EOK) | ||
|  |     { | ||
|  |         errno = -ECANCELED; | ||
|  |         return -1; | ||
|  |     } | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * The aio_error() function shall return the error status associated with the | ||
|  |  * aiocb structure referenced by the aiocbp argument. The error status for an | ||
|  |  * asynchronous I/O operation is the errno value that would be set by the corresponding | ||
|  |  * read(), write(), | ||
|  |  */ | ||
|  | int aio_error(const struct aiocb *cb) | ||
|  | { | ||
|  |     if (cb) | ||
|  |     { | ||
|  |         return cb->aio_result; | ||
|  |     } | ||
|  | 
 | ||
|  |     return -EINVAL; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * The aio_fsync() function shall asynchronously perform a file synchronization | ||
|  |  * operation, as specified by the op argument, for I/O operations associated with | ||
|  |  * the file indicated by the file descriptor aio_fildes member of the aiocb | ||
|  |  * structure referenced by the aiocbp argument and queued at the time of the | ||
|  |  * call to aio_fsync(). The function call shall return when the synchronization | ||
|  |  * request has been initiated or queued to the file or device (even when the data | ||
|  |  * cannot be synchronized immediately). | ||
|  |  * | ||
|  |  * option: If op is O_DSYNC, all currently queued I/O operations shall be completed | ||
|  |  * as if by a call to fdatasync(); that is, as defined for synchronized I/O data | ||
|  |  * integrity completion. | ||
|  |  * | ||
|  |  * option: If op is O_SYNC, all currently queued I/O operations shall be completed | ||
|  |  * as if by a call to fsync(); that is, as defined for synchronized I/O file integrity | ||
|  |  * completion. If the aio_fsync() function fails, or if the operation queued by | ||
|  |  * aio_fsync() fails, then outstanding I/O operations are not guaranteed to have | ||
|  |  * been completed. | ||
|  |  * | ||
|  |  * If aio_fsync() succeeds, then it is only the I/O that was queued at the time | ||
|  |  * of the call to aio_fsync() that is guaranteed to be forced to the relevant | ||
|  |  * completion state. The completion of subsequent I/O on the file descriptor is | ||
|  |  * not guaranteed to be completed in a synchronized fashion. | ||
|  |  * | ||
|  |  * The aiocbp argument refers to an asynchronous I/O control block. The aiocbp | ||
|  |  * value may be used as an argument to aio_error() and aio_return() in order to | ||
|  |  * determine the error status and return status, respectively, of the asynchronous | ||
|  |  * operation while it is proceeding. When the request is queued, the error status | ||
|  |  * for the operation is [EINPROGRESS]. When all data has been successfully transferred, | ||
|  |  * the error status shall be reset to reflect the success or failure of the operation. | ||
|  |  * If the operation does not complete successfully, the error status for the | ||
|  |  * operation shall be set to indicate the error. The aio_sigevent member determines | ||
|  |  * the asynchronous notification to occur as specified in Signal Generation and | ||
|  |  * Delivery when all operations have achieved synchronized I/O completion. All | ||
|  |  * other members of the structure referenced by aiocbp are ignored. If the control | ||
|  |  * block referenced by aiocbp becomes an illegal address prior to asynchronous | ||
|  |  * I/O completion, then the behavior is undefined. | ||
|  |  * | ||
|  |  * If the aio_fsync() function fails or aiocbp indicates an error condition, | ||
|  |  * data is not guaranteed to have been successfully transferred. | ||
|  |  */ | ||
|  | static void aio_fync_work(struct rt_work* work, void* work_data) | ||
|  | { | ||
|  |     int result; | ||
|  |     rt_base_t level; | ||
|  |     struct aiocb *cb = (struct aiocb*)work_data; | ||
|  | 
 | ||
|  |     RT_ASSERT(cb != RT_NULL); | ||
|  | 
 | ||
|  |     result = fsync(cb->aio_fildes); | ||
|  |     /* modify result */ | ||
|  |     level = rt_hw_interrupt_disable(); | ||
|  |     if (result < 0) | ||
|  |         cb->aio_result = errno; | ||
|  |     else | ||
|  |         cb->aio_result = 0; | ||
|  |     rt_hw_interrupt_enable(level); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * @brief   Initiates an asynchronous fsync operation. | ||
|  |  * | ||
|  |  * This function initiates an asynchronous fsync operation on the file associated | ||
|  |  * with the specified aiocb structure. The operation is queued to the workqueue | ||
|  |  * for execution. | ||
|  |  * | ||
|  |  * @param   op  The operation to be performed. This parameter is ignored. | ||
|  |  * @param   cb  Pointer to the aiocb structure representing the asynchronous fsync operation. | ||
|  |  * | ||
|  |  * @return  Returns 0 on success. | ||
|  |  */ | ||
|  | int aio_fsync(int op, struct aiocb *cb) | ||
|  | { | ||
|  |     rt_base_t level; | ||
|  |     if (!cb) return -EINVAL; | ||
|  | 
 | ||
|  |     level = rt_hw_interrupt_disable(); | ||
|  |     cb->aio_result = -EINPROGRESS; | ||
|  |     rt_hw_interrupt_enable(level); | ||
|  | 
 | ||
|  |     rt_work_init(&(cb->aio_work), aio_fync_work, cb); | ||
|  |     rt_workqueue_dowork(aio_queue, &(cb->aio_work)); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * @brief   Worker function for asynchronous read operation. | ||
|  |  * | ||
|  |  * This function performs the actual reading of data from the file associated with | ||
|  |  * the specified aiocb structure. It sets the result of the operation in the | ||
|  |  * aio_result field of the aiocb structure. | ||
|  |  * | ||
|  |  * @param   work       Pointer to the work item. | ||
|  |  * @param   work_data  Pointer to the aiocb structure representing the asynchronous read operation. | ||
|  |  */ | ||
|  | static void aio_read_work(struct rt_work* work, void* work_data) | ||
|  | { | ||
|  |     int len; | ||
|  |     rt_base_t level; | ||
|  |     uint8_t *buf_ptr; | ||
|  |     struct aiocb *cb = (struct aiocb*)work_data; | ||
|  | 
 | ||
|  |     buf_ptr = (uint8_t*)cb->aio_buf; | ||
|  | 
 | ||
|  |     /* seek to offset */ | ||
|  |     lseek(cb->aio_fildes, cb->aio_offset, SEEK_SET); | ||
|  |     len = read(cb->aio_fildes, &buf_ptr[cb->aio_offset], cb->aio_nbytes); | ||
|  | 
 | ||
|  |     /* modify result */ | ||
|  |     level = rt_hw_interrupt_disable(); | ||
|  |     if (len <= 0) | ||
|  |         cb->aio_result = errno; | ||
|  |     else | ||
|  |         cb->aio_result = len; | ||
|  |     rt_hw_interrupt_enable(level); | ||
|  | 
 | ||
|  |     return ; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * The aio_read() function shall read aiocbp->aio_nbytes from the file associated | ||
|  |  * with aiocbp->aio_fildes into the buffer pointed to by aiocbp->aio_buf. The | ||
|  |  * function call shall return when the read request has been initiated or queued | ||
|  |  * to the file or device (even when the data cannot be delivered immediately). | ||
|  |  * | ||
|  |  * If prioritized I/O is supported for this file, then the asynchronous operation | ||
|  |  * shall be submitted at a priority equal to a base scheduling priority minus | ||
|  |  * aiocbp->aio_reqprio. If Thread Execution Scheduling is not supported, then | ||
|  |  * the base scheduling priority is that of the calling process; | ||
|  |  * | ||
|  |  * otherwise, the base scheduling priority is that of the calling thread. | ||
|  |  * | ||
|  |  * The aiocbp value may be used as an argument to aio_error() and aio_return() | ||
|  |  * in order to determine the error status and return status, respectively, of | ||
|  |  * the asynchronous operation while it is proceeding. If an error condition is | ||
|  |  * encountered during queuing, the function call shall return without having | ||
|  |  * initiated or queued the request. The requested operation takes place at the | ||
|  |  * absolute position in the file as given by aio_offset, as if lseek() were called | ||
|  |  * immediately prior to the operation with an offset equal to aio_offset and a | ||
|  |  * whence equal to SEEK_SET. After a successful call to enqueue an asynchronous | ||
|  |  * I/O operation, the value of the file offset for the file is unspecified. | ||
|  |  * | ||
|  |  * The aio_sigevent member specifies the notification which occurs when the | ||
|  |  * request is completed. | ||
|  |  * | ||
|  |  * The aiocbp->aio_lio_opcode field shall be ignored by aio_read(). | ||
|  |  * | ||
|  |  * The aiocbp argument points to an aiocb structure. If the buffer pointed to by | ||
|  |  * aiocbp->aio_buf or the control block pointed to by aiocbp becomes an illegal | ||
|  |  * address prior to asynchronous I/O completion, then the behavior is undefined. | ||
|  |  * | ||
|  |  * Simultaneous asynchronous operations using the same aiocbp produce undefined | ||
|  |  * results. | ||
|  |  * | ||
|  |  * If synchronized I/O is enabled on the file associated with aiocbp->aio_fildes, | ||
|  |  * the behavior of this function shall be according to the definitions of synchronized | ||
|  |  * I/O data integrity completion and synchronized I/O file integrity completion. | ||
|  |  * | ||
|  |  * For any system action that changes the process memory space while an asynchronous | ||
|  |  * I/O is outstanding to the address range being changed, the result of that action | ||
|  |  * is undefined. | ||
|  |  * | ||
|  |  * For regular files, no data transfer shall occur past the offset maximum | ||
|  |  * established in the open file description associated with aiocbp->aio_fildes. | ||
|  |  * | ||
|  |  */ | ||
|  | int aio_read(struct aiocb *cb) | ||
|  | { | ||
|  |     rt_base_t level; | ||
|  | 
 | ||
|  |     if (!cb) return -EINVAL; | ||
|  |     if (cb->aio_offset < 0) return -EINVAL; | ||
|  | 
 | ||
|  |     level = rt_hw_interrupt_disable(); | ||
|  |     cb->aio_result = -EINPROGRESS; | ||
|  |     rt_hw_interrupt_enable(level); | ||
|  | 
 | ||
|  |     /* en-queue read work */ | ||
|  |     rt_work_init(&(cb->aio_work), aio_read_work, cb); | ||
|  |     rt_workqueue_dowork(aio_queue, &(cb->aio_work)); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * The aio_return() function shall return the return status associated with the | ||
|  |  * aiocb structure referenced by the aiocbp argument. The return status for an | ||
|  |  * asynchronous I/O operation is the value that would be returned by the corresponding | ||
|  |  * read(), write(), or fsync() function call. If the error status for the operation | ||
|  |  * is equal to [EINPROGRESS], then the return status for the operation is undefined. | ||
|  |  * The aio_return() function may be called exactly once to retrieve the return | ||
|  |  * status of a given asynchronous operation; thereafter, if the same aiocb structure | ||
|  |  * is used in a call to aio_return() or aio_error(), an error may be returned. | ||
|  |  * When the aiocb structure referred to by aiocbp is used to submit another asynchronous | ||
|  |  * operation, then aio_return() may be successfully used to retrieve the return | ||
|  |  * status of that operation. | ||
|  |  */ | ||
|  | ssize_t  aio_return(struct aiocb *cb) | ||
|  | { | ||
|  |     if (cb) | ||
|  |     { | ||
|  |         if (cb->aio_result < 0) | ||
|  |             rt_set_errno(cb->aio_result); | ||
|  | 
 | ||
|  |         return cb->aio_result; | ||
|  |     } | ||
|  | 
 | ||
|  |     return -EINVAL; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * The aio_suspend() function shall suspend the calling thread until at least | ||
|  |  * one of the asynchronous I/O operations referenced by the list argument has | ||
|  |  * completed, until a signal interrupts the function, or, if timeout is not NULL, | ||
|  |  * until the time interval specified by timeout has passed. If any of the aiocb | ||
|  |  * structures in the list correspond to completed asynchronous I/O operations | ||
|  |  * (that is, the error status for the operation is not equal to [EINPROGRESS]) | ||
|  |  * at the time of the call, the function shall return without suspending the | ||
|  |  * calling thread. The list argument is an array of pointers to asynchronous I/O | ||
|  |  * control blocks. The nent argument indicates the number of elements in the | ||
|  |  * array. Each aiocb structure pointed to has been used in initiating an asynchronous | ||
|  |  * I/O request via aio_read(), aio_write(), or lio_listio(). This array may | ||
|  |  * contain null pointers, which are ignored. If this array contains pointers | ||
|  |  * that refer to aiocb structures that have not been used in submitting asynchronous | ||
|  |  * I/O, the effect is undefined. | ||
|  |  * | ||
|  |  * If the time interval indicated in the timespec structure pointed to by timeout | ||
|  |  * passes before any of the I/O operations referenced by list are completed, then | ||
|  |  * aio_suspend() shall return with an error. | ||
|  |  */ | ||
|  | int aio_suspend(const struct aiocb *const list[], int nent, | ||
|  |              const struct timespec *timeout) | ||
|  | { | ||
|  |     return -ENOSYS; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * @brief   Worker function for asynchronous write operation. | ||
|  |  * | ||
|  |  * This function performs the actual writing of data to the file associated with | ||
|  |  * the specified aiocb structure. It sets the result of the operation in the | ||
|  |  * aio_result field of the aiocb structure. | ||
|  |  * | ||
|  |  * @param   work       Pointer to the work item. | ||
|  |  * @param   work_data  Pointer to the aiocb structure representing the asynchronous write operation. | ||
|  |  */ | ||
|  | static void aio_write_work(struct rt_work* work, void* work_data) | ||
|  | { | ||
|  |     rt_base_t level; | ||
|  |     int len, oflags; | ||
|  |     uint8_t *buf_ptr; | ||
|  |     struct aiocb *cb = (struct aiocb*)work_data; | ||
|  | 
 | ||
|  |     buf_ptr = (uint8_t*)cb->aio_buf; | ||
|  | 
 | ||
|  |     /* whether seek offset */ | ||
|  |     oflags = fcntl(cb->aio_fildes, F_GETFL, 0); | ||
|  |     if ((oflags & O_APPEND) == 0) | ||
|  |     { | ||
|  |         lseek(cb->aio_fildes, SEEK_SET, cb->aio_offset); | ||
|  |     } | ||
|  | 
 | ||
|  |     /* write data */ | ||
|  |     len = write(cb->aio_fildes, buf_ptr, cb->aio_nbytes); | ||
|  | 
 | ||
|  |     /* modify result */ | ||
|  |     level = rt_hw_interrupt_disable(); | ||
|  |     if (len <= 0) | ||
|  |         cb->aio_result = errno; | ||
|  |     else | ||
|  |         cb->aio_result = len; | ||
|  |     rt_hw_interrupt_enable(level); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * The aio_write() function shall write aiocbp->aio_nbytes to the file associated | ||
|  |  * with aiocbp->aio_fildes from the buffer pointed to by aiocbp->aio_buf. The | ||
|  |  * function shall return when the write request has been initiated or, at a minimum, | ||
|  |  * queued to the file or device. | ||
|  |  * | ||
|  |  * The aiocbp argument may be used as an argument to aio_error() and aio_return() | ||
|  |  * in order to determine the error status and return status, respectively, of the | ||
|  |  * asynchronous operation while it is proceeding. | ||
|  |  * | ||
|  |  * The aiocbp argument points to an aiocb structure. If the buffer pointed to by | ||
|  |  * aiocbp->aio_buf or the control block pointed to by aiocbp becomes an illegal | ||
|  |  * address prior to asynchronous I/O completion, then the behavior is undefined. | ||
|  |  * | ||
|  |  * If O_APPEND is not set for the file descriptor aio_fildes, then the requested | ||
|  |  * operation shall take place at the absolute position in the file as given by | ||
|  |  * aio_offset, as if lseek() were called immediately prior to the operation with | ||
|  |  * an offset equal to aio_offset and a whence equal to SEEK_SET. If O_APPEND is | ||
|  |  * set for the file descriptor, or if aio_fildes is associated with a device that | ||
|  |  * is incapable of seeking, write operations append to the file in the same order | ||
|  |  * as the calls were made, except under circumstances described in Asynchronous | ||
|  |  * I/O. After a successful call to enqueue an asynchronous I/O operation, the value | ||
|  |  * of the file offset for the file is unspecified. | ||
|  |  * | ||
|  |  * The aio_sigevent member specifies the notification which occurs when the request | ||
|  |  * is completed. | ||
|  |  * | ||
|  |  * The aiocbp->aio_lio_opcode field shall be ignored by aio_write(). | ||
|  |  * | ||
|  |  * Simultaneous asynchronous operations using the same aiocbp produce undefined | ||
|  |  * results. | ||
|  |  * | ||
|  |  * If synchronized I/O is enabled on the file associated with aiocbp->aio_fildes, | ||
|  |  * the behavior of this function shall be according to the definitions of synchronized | ||
|  |  * I/O data integrity completion, and synchronized I/O file integrity completion. | ||
|  |  * | ||
|  |  * For regular files, no data transfer shall occur past the offset maximum established | ||
|  |  * in the open file description associated with aiocbp->aio_fildes. | ||
|  |  */ | ||
|  | int aio_write(struct aiocb *cb) | ||
|  | { | ||
|  |     int oflags; | ||
|  |     rt_base_t level; | ||
|  | 
 | ||
|  |     if (!cb || (cb->aio_buf == NULL)) return -EINVAL; | ||
|  | 
 | ||
|  |     /* check access mode */ | ||
|  |     oflags = fcntl(cb->aio_fildes, F_GETFL, 0); | ||
|  |     /* If the flag is not in write only or read-write mode, it cannot be written then an invalid parameter is returned  */ | ||
|  |     if ((oflags & O_ACCMODE) != O_WRONLY && | ||
|  |         (oflags & O_ACCMODE) != O_RDWR) | ||
|  |         return -EINVAL; | ||
|  | 
 | ||
|  |     level = rt_hw_interrupt_disable(); | ||
|  |     cb->aio_result = -EINPROGRESS; | ||
|  |     rt_hw_interrupt_enable(level); | ||
|  | 
 | ||
|  |     rt_work_init(&(cb->aio_work), aio_write_work, cb); | ||
|  |     rt_workqueue_dowork(aio_queue, &(cb->aio_work)); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * The lio_listio() function shall initiate a list of I/O requests with a single | ||
|  |  * function call. | ||
|  |  * | ||
|  |  * The mode argument takes one of the values LIO_WAIT or LIO_NOWAIT declared in | ||
|  |  * <aio.h> and determines whether the function returns when the I/O operations | ||
|  |  * have been completed, or as soon as the operations have been queued. If the | ||
|  |  * mode argument is LIO_WAIT, the function shall wait until all I/O is complete | ||
|  |  * and the sig argument shall be ignored. | ||
|  |  * | ||
|  |  * If the mode argument is LIO_NOWAIT, the function shall return immediately, and | ||
|  |  * asynchronous notification shall occur, according to the sig argument, when all | ||
|  |  * the I/O operations complete. If sig is NULL, then no asynchronous notification | ||
|  |  * shall occur. If sig is not NULL, asynchronous notification occurs as specified | ||
|  |  * in Signal Generation and Delivery when all the requests in list have completed. | ||
|  |  * | ||
|  |  * The I/O requests enumerated by list are submitted in an unspecified order. | ||
|  |  * | ||
|  |  * The list argument is an array of pointers to aiocb structures. The array contains | ||
|  |  * nent elements. The array may contain NULL elements, which shall be ignored. | ||
|  |  * | ||
|  |  * If the buffer pointed to by list or the aiocb structures pointed to by the | ||
|  |  * elements of the array list become illegal addresses before all asynchronous I/O | ||
|  |  * completed and, if necessary, the notification is sent, then the behavior is | ||
|  |  * undefined. If the buffers pointed to by the aio_buf member of the aiocb structure | ||
|  |  * pointed to by the elements of the array list become illegal addresses prior to | ||
|  |  * the asynchronous I/O associated with that aiocb structure being completed, the | ||
|  |  * behavior is undefined. | ||
|  |  * | ||
|  |  * The aio_lio_opcode field of each aiocb structure specifies the operation to be | ||
|  |  * performed. The supported operations are LIO_READ, LIO_WRITE, and LIO_NOP; these | ||
|  |  * symbols are defined in <aio.h>. The LIO_NOP operation causes the list entry to | ||
|  |  * be ignored. If the aio_lio_opcode element is equal to LIO_READ, then an I/O operation | ||
|  |  * is submitted as if by a call to aio_read() with the aiocbp equal to the address | ||
|  |  * of the aiocb structure. If the aio_lio_opcode element is equal to LIO_WRITE, then | ||
|  |  * an I/O operation is submitted as if by a call to aio_write() with the aiocbp equal | ||
|  |  * to the address of the aiocb structure. | ||
|  |  * | ||
|  |  * The aio_fildes member specifies the file descriptor on which the operation is to | ||
|  |  * be performed. | ||
|  |  * | ||
|  |  * The aio_buf member specifies the address of the buffer to or from which the data | ||
|  |  * is transferred. | ||
|  |  * | ||
|  |  * The aio_nbytes member specifies the number of bytes of data to be transferred. | ||
|  |  * | ||
|  |  * The members of the aiocb structure further describe the I/O operation to be | ||
|  |  * performed, in a manner identical to that of the corresponding aiocb structure | ||
|  |  * when used by the aio_read() and aio_write() functions. | ||
|  |  * | ||
|  |  * The nent argument specifies how many elements are members of the list; that is, | ||
|  |  * the length of the array. | ||
|  |  * | ||
|  |  * The behavior of this function is altered according to the definitions of synchronized | ||
|  |  * I/O data integrity completion and synchronized I/O file integrity completion if | ||
|  |  * synchronized I/O is enabled on the file associated with aio_fildes. | ||
|  |  * | ||
|  |  * For regular files, no data transfer shall occur past the offset maximum established | ||
|  |  * in the open file description associated with aiocbp->aio_fildes. | ||
|  |  * | ||
|  |  * If sig->sigev_notify is SIGEV_THREAD and sig->sigev_notify_attributes is a | ||
|  |  * non-null pointer and the block pointed to by this pointer becomes an illegal | ||
|  |  * address prior to all asynchronous I/O being completed, then the behavior is | ||
|  |  * undefined. | ||
|  |  */ | ||
|  | int lio_listio(int mode, struct aiocb * const list[], int nent, | ||
|  |             struct sigevent *sig) | ||
|  | { | ||
|  |     return -ENOSYS; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * @brief   Initializes the asynchronous I/O system. | ||
|  |  * | ||
|  |  * This function initializes the asynchronous I/O system by creating a workqueue | ||
|  |  * for asynchronous I/O operations. | ||
|  |  * | ||
|  |  * @return  Returns 0 on success. | ||
|  |  */ | ||
|  | int aio_system_init(void) | ||
|  | { | ||
|  |     aio_queue = rt_workqueue_create("aio", 2048, RT_THREAD_PRIORITY_MAX/2); | ||
|  |     RT_ASSERT(aio_queue != NULL); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | INIT_COMPONENT_EXPORT(aio_system_init); |