From ea06ccf99b5d9fb74f1c57f9a6cbc42758f55442 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 11 Oct 2014 08:15:23 -0600 Subject: AIO now also supports socket transfers --- nuttx/fs/aio/aio.h | 37 ++++++++++++++++---- nuttx/fs/aio/aio_fsync.c | 4 +-- nuttx/fs/aio/aio_read.c | 45 ++++++++++++++++++------ nuttx/fs/aio/aio_write.c | 85 ++++++++++++++++++++++++++++++--------------- nuttx/fs/aio/aioc_contain.c | 48 +++++++++++++++++++++---- 5 files changed, 166 insertions(+), 53 deletions(-) (limited to 'nuttx/fs') diff --git a/nuttx/fs/aio/aio.h b/nuttx/fs/aio/aio.h index 0f811e9ea..f74269a19 100644 --- a/nuttx/fs/aio/aio.h +++ b/nuttx/fs/aio/aio.h @@ -48,6 +48,7 @@ #include #include +#include #ifdef CONFIG_FS_AIO @@ -62,6 +63,21 @@ # define CONFIG_FS_NAIOC 8 #endif +#undef AIO_HAVE_FILEP +#undef AIO_HAVE_PSOCK + +#if CONFIG_NFILE_DESCRIPTORS > 0 +# define AIO_HAVE_FILEP +#endif + +#if defined(CONFIG_NET_TCP) && CONFIG_NSOCKET_DESCRIPTORS > 0 +# define AIO_HAVE_PSOCK +#endif + +#if !defined(AIO_HAVE_FILEP) && !defined(AIO_HAVE_PSOCK) +# error AIO needs file and/or socket descriptors +#endif + /**************************************************************************** * Public Types ****************************************************************************/ @@ -73,13 +89,22 @@ struct file; struct aio_container_s { - dq_entry_t aioc_link; /* Supports a doubly linked list */ - FAR struct aiocb *aioc_aiocbp; /* The contained AIO control block */ - FAR struct file *aioc_filep; /* File structure to use with the I/O */ - struct work_s aioc_work; /* Used to defer I/O to the work thread */ - pid_t aioc_pid; /* ID of the waiting task */ + dq_entry_t aioc_link; /* Supports a doubly linked list */ + FAR struct aiocb *aioc_aiocbp; /* The contained AIO control block */ + union + { +#ifdef AIO_HAVE_FILEP + FAR struct file *aioc_filep; /* File structure to use with the I/O */ +#endif +#ifdef AIO_HAVE_PSOCK + FAR struct socket *aioc_psock; /* Socket structure to use with the I/O */ +#endif + FAR void *ptr; /* Generic pointer to FAR data */ + } u; + struct work_s aioc_work; /* Used to defer I/O to the work thread */ + pid_t aioc_pid; /* ID of the waiting task */ #ifdef CONFIG_PRIORITY_INHERITANCE - uint8_t aioc_prio; /* Priority of the waiting task */ + uint8_t aioc_prio; /* Priority of the waiting task */ #endif }; diff --git a/nuttx/fs/aio/aio_fsync.c b/nuttx/fs/aio/aio_fsync.c index cfb2522e6..ad816264b 100644 --- a/nuttx/fs/aio/aio_fsync.c +++ b/nuttx/fs/aio/aio_fsync.c @@ -110,9 +110,9 @@ static void aio_fsync_worker(FAR void *arg) #endif aiocbp = aioc_decant(aioc); - /* Perform the fsync using aioc_filep */ + /* Perform the fsync using u.aioc_filep */ - ret = file_fsync(aioc->aioc_filep); + ret = file_fsync(aioc->u.aioc_filep); if (ret < 0) { int errcode = get_errno(); diff --git a/nuttx/fs/aio/aio_read.c b/nuttx/fs/aio/aio_read.c index 3a3c5f234..c020c4ced 100644 --- a/nuttx/fs/aio/aio_read.c +++ b/nuttx/fs/aio/aio_read.c @@ -46,6 +46,8 @@ #include #include +#include + #include "aio/aio.h" #ifdef CONFIG_FS_AIO @@ -108,16 +110,39 @@ static void aio_read_worker(FAR void *arg) #endif aiocbp = aioc_decant(aioc); - /* Perform the read using: - * - * aioc_filep - File structure pointer - * aio_buf - Location of buffer - * aio_nbytes - Length of transfer - * aio_offset - File offset - */ - - nread = file_pread(aioc->aioc_filep, (FAR void *)aiocbp->aio_buf, - aiocbp->aio_nbytes, aiocbp->aio_offset); +#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK) + if (aioc->fildes >= CONFIG_NFILE_DESCRIPTORS) +#endif +#ifdef AIO_HAVE_FILEP + { + /* Perform the file read using: + * + * u.aioc_filep - File structure pointer + * aio_buf - Location of buffer + * aio_nbytes - Length of transfer + * aio_offset - File offset + */ + + nread = file_pread(aioc->u.aioc_filep, (FAR void *)aiocbp->aio_buf, + aiocbp->aio_nbytes, aiocbp->aio_offset); + } +#endif +#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK) + else +#endif +#ifdef AIO_HAVE_PSOCK + { + /* Perform the socket receive using: + * + * u.aioc_psock - Socket structure pointer + * aio_buf - Location of buffer + * aio_nbytes - Length of transfer + */ + + nread = psock_recv(aioc->u.aioc_psock, (FAR void *)aiocbp->aio_buf, + aiocbp->aio_nbytes, 0); + } +#endif /* Set the result of the read */ diff --git a/nuttx/fs/aio/aio_write.c b/nuttx/fs/aio/aio_write.c index 497f8010d..a3cf99cab 100644 --- a/nuttx/fs/aio/aio_write.c +++ b/nuttx/fs/aio/aio_write.c @@ -76,6 +76,7 @@ * Name: file_fcntl ****************************************************************************/ +#ifdef AIO_HAVE_FILEP static inline int file_fcntl(FAR struct file *filep, int cmd, ...) { va_list ap; @@ -86,6 +87,7 @@ static inline int file_fcntl(FAR struct file *filep, int cmd, ...) va_end(ap); return ret; } +#endif /**************************************************************************** * Name: aio_write_worker @@ -126,23 +128,28 @@ static void aio_write_worker(FAR void *arg) #endif aiocbp = aioc_decant(aioc); - /* Call fcntl(F_GETFL) to get the file open mode. */ - - oflags = file_fcntl(aioc->aioc_filep, F_GETFL); - if (oflags < 0) - { - int errcode = get_errno(); - fdbg("ERROR: fcntl failed: %d\n", errcode); - aiocbp->aio_result = -errcode; - } - else +#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK) + if (aioc->fildes >= CONFIG_NFILE_DESCRIPTORS) +#endif +#ifdef AIO_HAVE_FILEP { + /* Call fcntl(F_GETFL) to get the file open mode. */ + + oflags = file_fcntl(aioc->u.aioc_filep, F_GETFL); + if (oflags < 0) + { + int errcode = get_errno(); + fdbg("ERROR: fcntl failed: %d\n", errcode); + aiocbp->aio_result = -errcode; + goto errout: + } + /* Perform the write using: * - * aioc_filep - File descriptor - * aio_buf - Location of buffer - * aio_nbytes - Length of transfer - * aio_offset - File offset + * u.aioc_filep - File structure pointer + * aio_buf - Location of buffer + * aio_nbytes - Length of transfer + * aio_offset - File offset */ /* Check if O_APPEND is set in the file open flags */ @@ -151,32 +158,54 @@ static void aio_write_worker(FAR void *arg) { /* Append to the current file position */ - nwritten = file_write(aioc->aioc_filep, + nwritten = file_write(aioc->u.aioc_filep, (FAR const void *)aiocbp->aio_buf, aiocbp->aio_nbytes); } else { - nwritten = file_pwrite(aioc->aioc_filep, + nwritten = file_pwrite(aioc->u.aioc_filep, (FAR const void *)aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset); } + } +#endif +#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK) + else +#endif +#ifdef AIO_HAVE_PSOCK + { + /* Perform the send using: + * + * u.aioc_psock - Socket structure pointer + * aio_buf - Location of buffer + * aio_nbytes - Length of transfer + */ - /* Set the result of the write */ + nwritten = psock_send(aioc->u.aioc_psock, + (FAR const void *)aiocbp->aio_buf, + aiocbp->aio_nbytes, 0); + } +#endif - if (nwritten < 0) - { - int errcode = get_errno(); - fdbg("ERROR: write/pwrite failed: %d\n", errcode); - DEBUGASSERT(errcode > 0); - aiocbp->aio_result = -errcode; - } - else - { - aiocbp->aio_result = nwritten; - } + /* Check the result of the write */ + + if (nwritten < 0) + { + int errcode = get_errno(); + fdbg("ERROR: write/pwrite failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + aiocbp->aio_result = -errcode; } + else + { + aiocbp->aio_result = nwritten; + } + +#ifdef AIO_HAVE_FILEP +errout: +#endif /* Signal the client */ diff --git a/nuttx/fs/aio/aioc_contain.c b/nuttx/fs/aio/aioc_contain.c index 98fcf7821..50b2f9d43 100644 --- a/nuttx/fs/aio/aioc_contain.c +++ b/nuttx/fs/aio/aioc_contain.c @@ -42,6 +42,7 @@ #include #include +#include #include "aio/aio.h" @@ -90,20 +91,53 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp) { FAR struct aio_container_s *aioc; - FAR struct file *filep; + union + { +#ifdef AIO_HAVE_FILEP + FAR struct file *filep; +#endif +#ifdef AIO_HAVE_FILEP + FAR struct socket *psock; +#endif + FAR void *ptr; + } u; #ifdef CONFIG_PRIORITY_INHERITANCE struct sched_param param; #endif - /* Get the file structure corresponding to the file descriptor. */ +#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK) + if (aioc->fildes >= CONFIG_NFILE_DESCRIPTORS) +#endif +#ifdef AIO_HAVE_FILEP + { + /* Get the file structure corresponding to the file descriptor. */ + + u.filep = fs_getfilep(aiocbp->aio_fildes); + if (!u.filep) + { + /* The errno value has already been set */ - filep = fs_getfilep(aiocbp->aio_fildes); - if (!filep) + return NULL; + } + } +#endif +#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK) + else +#endif +#ifdef AIO_HAVE_PSOCK { - /* The errno value has already been set */ + /* Get the socket structure corresponding to the socket descriptor */ - return NULL; + u.psock = sockfd_socket(aiocbp->aio_fildes); + if (!u.psock) + { + /* Does not set the errno. EBADF is the most likely explanation. */ + + set_errno(EBADF); + return NULL; + } } +#endif /* Allocate the AIO control block container, waiting for one to become * available if necessary. This should never fail. @@ -116,7 +150,7 @@ FAR struct aio_container_s *aio_contain(FAR struct aiocb *aiocbp) memset(aioc, 0, sizeof(struct aio_container_s)); aioc->aioc_aiocbp = aiocbp; - aioc->aioc_filep = filep; + aioc->u.aioc_filep = u.ptr; aioc->aioc_pid = getpid(); #ifdef CONFIG_PRIORITY_INHERITANCE -- cgit v1.2.3