diff options
-rw-r--r-- | nuttx/TODO | 20 | ||||
-rw-r--r-- | nuttx/fs/aio/aio.h | 37 | ||||
-rw-r--r-- | nuttx/fs/aio/aio_fsync.c | 4 | ||||
-rw-r--r-- | nuttx/fs/aio/aio_read.c | 45 | ||||
-rw-r--r-- | nuttx/fs/aio/aio_write.c | 85 | ||||
-rw-r--r-- | nuttx/fs/aio/aioc_contain.c | 48 | ||||
-rw-r--r-- | nuttx/include/aio.h | 2 | ||||
-rw-r--r-- | nuttx/include/nuttx/net/net.h | 9 | ||||
-rw-r--r-- | nuttx/net/socket/net_sockets.c | 2 |
9 files changed, 175 insertions, 77 deletions
diff --git a/nuttx/TODO b/nuttx/TODO index 0cd977eff..c4872109c 100644 --- a/nuttx/TODO +++ b/nuttx/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated October 10, 2014) +NuttX TODO List (Last updated October 11, 2014) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -18,7 +18,7 @@ nuttx/ (13) Network (net/, drivers/net) (4) USB (drivers/usbdev, drivers/usbhost) (10) Libraries (libc/, ) - (12) File system/Generic drivers (fs/, drivers/) + (11) File system/Generic drivers (fs/, drivers/) (6) Graphics subystem (graphics/) (1) Pascal add-on (pcode/) (1) Documentation (Documentation/) @@ -1163,22 +1163,6 @@ o File system / Generic drivers (fs/, drivers/) Status: Open Priority: Medium - Title: ASYNCHRONOUS I/O DOES NOT WORK WITH SOCKETS - Description: The current asynchronous I/O logic will only work with - file descriptions. If given a socket descriptor, the - AIO interfaces will fail with EBADF. The existing logic - should be extended to handle socket descriptors. - - This should be an easy fix: There could have to be a - tagged union of a struct file and struct socket in the - AIO container and the worker logic would have to select - the correct low-level, internal interface. There would - be no lseek'ing on sockets. - - Status: Open - Priority: Pretty high because this limits the usefulness of the - AIO implementation. - o Graphics subsystem (graphics/) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 <queue.h> #include <nuttx/wqueue.h> +#include <nuttx/net/net.h> #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 <errno.h> #include <debug.h> +#include <nuttx/net/net.h> + #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 <sched.h> #include <nuttx/fs/fs.h> +#include <nuttx/net/net.h> #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 diff --git a/nuttx/include/aio.h b/nuttx/include/aio.h index b323e01b3..183caec06 100644 --- a/nuttx/include/aio.h +++ b/nuttx/include/aio.h @@ -125,7 +125,7 @@ struct aiocb FAR volatile void *aio_buf; /* Location of buffer */ off_t aio_offset; /* File offset */ size_t aio_nbytes; /* Length of transfer */ -#if CONFIG_NFILE_DESCRIPTORS > 127 +#if (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS) > 127 int16_t aio_fildes; /* File descriptor (should be int) */ #else int8_t aio_fildes; /* File descriptor (should be int) */ diff --git a/nuttx/include/nuttx/net/net.h b/nuttx/include/nuttx/net/net.h index f2cf839b3..23558b427 100644 --- a/nuttx/include/nuttx/net/net.h +++ b/nuttx/include/nuttx/net/net.h @@ -302,16 +302,17 @@ void net_initlist(FAR struct socketlist *list); void net_releaselist(FAR struct socketlist *list); /**************************************************************************** - * Name: sockfd_release + * Name: sockfd_socket * * Description: - * Free the socket by its socket descriptor. + * Given a socket descriptor, return the underlying socket structure. * * Input Parameters: - * sockfd - Socket descriptor identifies the socket to be released. + * sockfd - The socket descriptor index o use. * * Returned Value: - * None + * On success, a reference to the socket structure associated with the + * the socket descriptor is returned. NULL is returned on any failure. * ****************************************************************************/ diff --git a/nuttx/net/socket/net_sockets.c b/nuttx/net/socket/net_sockets.c index 632d15aa5..a98d67fc1 100644 --- a/nuttx/net/socket/net_sockets.c +++ b/nuttx/net/socket/net_sockets.c @@ -94,7 +94,7 @@ static void _net_semtake(FAR struct socketlist *list) ****************************************************************************/ /**************************************************************************** - * Name: + * Name: net_initlist * * Description: * Initialize a list of sockets for a new task |