Modify logic to use AIO control block container
This commit is contained in:
parent
52ce95b8b8
commit
a5b4a4161b
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* libc/aio/aio_cancel.c
|
||||
* fs/aio/aio_cancel.c
|
||||
*
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -60,11 +60,11 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
@ -95,7 +95,7 @@
|
||||
* will not be modified by aio_cancel().
|
||||
*
|
||||
* Input Parameters:
|
||||
* fildes - Not used in this implmentation
|
||||
* fildes - Not used in this implementation
|
||||
* aiocbp - Points to the asynchronous I/O control block for a particular
|
||||
* request to be cancelled.
|
||||
*
|
||||
@ -122,6 +122,7 @@
|
||||
|
||||
int aio_cancel(int fildes, FAR struct aiocb *aiocbp)
|
||||
{
|
||||
FAR struct aio_container_s *aioc;
|
||||
int status;
|
||||
int ret;
|
||||
|
||||
@ -143,15 +144,37 @@ int aio_cancel(int fildes, FAR struct aiocb *aiocbp)
|
||||
|
||||
if (aiocbp->aio_result == -EINPROGRESS)
|
||||
{
|
||||
/* No ... attempt to cancel the I/O. There are two possibilities: (1)
|
||||
* the work has already been started and is no longer queued, or (2)
|
||||
* the work has not been started and is still in the work queue. Only
|
||||
* the second case can be cancelled. work_cancel() will return
|
||||
* -ENOENT in the first case.
|
||||
*/
|
||||
/* No.. Find the container for this AIO control block */
|
||||
|
||||
status = work_cancel(LPWORK, &aiocbp->aio_work);
|
||||
ret = status >= 0 ? AIO_CANCELED : AIO_NOTCANCELED;
|
||||
aio_lock();
|
||||
for (aioc = (FAR struct aio_container_s *)g_aio_pending.head;
|
||||
aioc && aioc->aioc_aiocbp != aiocbp;
|
||||
aioc = (FAR struct aio_container_s *)aioc->aioc_link.flink);
|
||||
aio_unlock();
|
||||
|
||||
/* Did we find the container? */
|
||||
|
||||
if (!aioc)
|
||||
{
|
||||
/* No.. the aio_result says that that the transfer is pending,
|
||||
* but there is no container in the pending I/O list. I am
|
||||
* confused.
|
||||
*/
|
||||
|
||||
ret = AIO_ALLDONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Yes... attempt to cancel the I/O. There are two possibilities:
|
||||
* (1) the work has already been started and is no longer queued,
|
||||
* or (2) the work has not been started and is still in the work
|
||||
* queue. Only the second case can be cancelled. work_cancel()
|
||||
* will return -ENOENT in the first case.
|
||||
*/
|
||||
|
||||
status = work_cancel(LPWORK, &aioc->aioc_work);
|
||||
ret = status >= 0 ? AIO_CANCELED : AIO_NOTCANCELED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* libc/aio/aio_fsync.c
|
||||
* fs/aio/aio_fsync.c
|
||||
*
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -54,18 +54,17 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
@ -90,10 +89,20 @@
|
||||
|
||||
static void aio_fsync_worker(FAR void *arg)
|
||||
{
|
||||
FAR struct aiocb *aiocbp = (FAR struct aiocb *)arg;
|
||||
DEBUGASSERT(arg);
|
||||
FAR struct aio_container_s *aioc = (FAR struct aio_container_s *)arg;
|
||||
FAR struct aiocb *aiocbp;
|
||||
pid_t pid;
|
||||
int ret;
|
||||
|
||||
/* Get the information from the container, decant the AIO control block,
|
||||
* and free the container before starting any I/O. That will minimize
|
||||
* the delays by any other threads waiting for a pre-allocated container.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(aioc && aioc->aioc_aiocbp);
|
||||
pid = aioc->aioc_pid;
|
||||
aiocbp = aioc_decant(aioc);
|
||||
|
||||
/* Perform the fsync using aio_fildes */
|
||||
|
||||
ret = fsync(aiocbp->aio_fildes);
|
||||
@ -111,7 +120,7 @@ static void aio_fsync_worker(FAR void *arg)
|
||||
|
||||
/* Signal the client */
|
||||
|
||||
(void)aio_signal(aiocbp);
|
||||
(void)aio_signal(pid, aiocbp);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -169,7 +178,7 @@ static void aio_fsync_worker(FAR void *arg)
|
||||
* aiocbp - A pointer to an instance of struct aiocb
|
||||
*
|
||||
* Returned Value:
|
||||
* The aio_fsync() function will return the value 0 if the I/O operation is
|
||||
* The aio_fsync() function will return the value 0 if the I/O operation is
|
||||
* successfully queued; otherwise, the function will return the value -1 and
|
||||
* set errno to indicate the error.
|
||||
*
|
||||
@ -198,6 +207,7 @@ static void aio_fsync_worker(FAR void *arg)
|
||||
|
||||
int aio_fsync(int op, FAR struct aiocb *aiocbp)
|
||||
{
|
||||
FAR struct aio_container_s *aioc;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(op == O_SYNC /* || op == O_DSYNC */);
|
||||
@ -208,13 +218,16 @@ int aio_fsync(int op, FAR struct aiocb *aiocbp)
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
/* Save the ID of the calling, client thread */
|
||||
/* Create a container for the AIO control block. This will not fail but
|
||||
* may cause us to block if there are insufficient resources to satisfy
|
||||
* the request.
|
||||
*/
|
||||
|
||||
aiocbp->aio_pid = getpid();
|
||||
aioc = aio_contain(aiocbp);
|
||||
|
||||
/* Defer the work to the worker thread */
|
||||
|
||||
ret = work_queue(LPWORK, &aiocbp->aio_work, aio_fsync_worker, aiocbp, 0);
|
||||
ret = work_queue(LPWORK, &aioc->aioc_work, aio_fsync_worker, aioc, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
aiocbp->aio_result = ret;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* libc/aio/aio_read.c
|
||||
* fs/aio/aio_read.c
|
||||
*
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -55,18 +55,17 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
@ -91,10 +90,20 @@
|
||||
|
||||
static void aio_read_worker(FAR void *arg)
|
||||
{
|
||||
FAR struct aiocb *aiocbp = (FAR struct aiocb *)arg;
|
||||
DEBUGASSERT(arg);
|
||||
FAR struct aio_container_s *aioc = (FAR struct aio_container_s *)arg;
|
||||
FAR struct aiocb *aiocbp;
|
||||
pid_t pid;
|
||||
ssize_t nread;
|
||||
|
||||
/* Get the information from the container, decant the AIO control block,
|
||||
* and free the container before starting any I/O. That will minimize
|
||||
* the delays by any other threads waiting for a pre-allocated container.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(aioc && aioc->aioc_aiocbp);
|
||||
pid = aioc->aioc_pid;
|
||||
aiocbp = aioc_decant(aioc);
|
||||
|
||||
/* Perform the read using:
|
||||
*
|
||||
* aio_fildes - File descriptor
|
||||
@ -122,7 +131,7 @@ static void aio_read_worker(FAR void *arg)
|
||||
|
||||
/* Signal the client */
|
||||
|
||||
(void)aio_signal(aiocbp);
|
||||
(void)aio_signal(pid, aiocbp);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -247,6 +256,7 @@ static void aio_read_worker(FAR void *arg)
|
||||
|
||||
int aio_read(FAR struct aiocb *aiocbp)
|
||||
{
|
||||
FAR struct aio_container_s *aioc;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(aiocbp);
|
||||
@ -256,13 +266,16 @@ int aio_read(FAR struct aiocb *aiocbp)
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
/* Save the ID of the calling, client thread */
|
||||
/* Create a container for the AIO control block. This will not fail but
|
||||
* may cause us to block if there are insufficient resources to satisfy
|
||||
* the request.
|
||||
*/
|
||||
|
||||
aiocbp->aio_pid = getpid();
|
||||
aioc = aio_contain(aiocbp);
|
||||
|
||||
/* Defer the work to the worker thread */
|
||||
|
||||
ret = work_queue(LPWORK, &aiocbp->aio_work, aio_read_worker, aiocbp, 0);
|
||||
ret = work_queue(LPWORK, &aioc->aioc_work, aio_read_worker, aioc, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
aiocbp->aio_result = ret;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* libc/aio/aio_signal.c
|
||||
* fs/aio/aio_signal.c
|
||||
*
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -39,6 +39,7 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <aio.h>
|
||||
@ -53,18 +54,17 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
@ -81,6 +81,7 @@
|
||||
* Signal the client that an I/O has completed.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pid - ID of the task to signal
|
||||
* aiocbp - Pointer to the asynchronous I/O state structure that includes
|
||||
* information about how to signal the client
|
||||
*
|
||||
@ -93,14 +94,14 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int aio_signal(FAR struct aiocb *aiocbp)
|
||||
int aio_signal(pid_t pid, FAR struct aiocb *aiocbp)
|
||||
{
|
||||
int errcode;
|
||||
int status;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(aiocbp);
|
||||
|
||||
|
||||
ret = OK; /* Assume success */
|
||||
|
||||
/* Signal the client */
|
||||
@ -108,10 +109,10 @@ int aio_signal(FAR struct aiocb *aiocbp)
|
||||
if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
|
||||
{
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
status = sigqueue(aiocbp->aio_pid, aiocbp->aio_sigevent.sigev_signo,
|
||||
status = sigqueue(pid, aiocbp->aio_sigevent.sigev_signo,
|
||||
aiocbp->aio_sigevent.sigev_value);
|
||||
#else
|
||||
status = sigqueue(aiocbp->aio_pid, aiocbp->aio_sigevent.sigev_sign,
|
||||
status = sigqueue(pid, aiocbp->aio_sigevent.sigev_sign,
|
||||
aiocbp->aio_sigevent.sigev_value.sival_ptr);
|
||||
#endif
|
||||
if (ret < 0)
|
||||
@ -126,7 +127,7 @@ int aio_signal(FAR struct aiocb *aiocbp)
|
||||
* on sig_suspend();
|
||||
*/
|
||||
|
||||
status = kill(aiocbp->aio_pid, SIGPOLL);
|
||||
status = kill(pid, SIGPOLL);
|
||||
if (status && ret == OK)
|
||||
{
|
||||
errcode = get_errno();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* libc/aio/aio_write.c
|
||||
* fs/aio/aio_write.c
|
||||
*
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -56,18 +56,17 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
@ -92,11 +91,21 @@
|
||||
|
||||
static void aio_write_worker(FAR void *arg)
|
||||
{
|
||||
FAR struct aiocb *aiocbp = (FAR struct aiocb *)arg;
|
||||
DEBUGASSERT(arg);
|
||||
FAR struct aio_container_s *aioc = (FAR struct aio_container_s *)arg;
|
||||
FAR struct aiocb *aiocbp;
|
||||
pid_t pid;
|
||||
ssize_t nwritten;
|
||||
int oflags;
|
||||
|
||||
/* Get the information from the container, decant the AIO control block,
|
||||
* and free the container before starting any I/O. That will minimize
|
||||
* the delays by any other threads waiting for a pre-allocated container.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(aioc && aioc->aioc_aiocbp);
|
||||
pid = aioc->aioc_pid;
|
||||
aiocbp = aioc_decant(aioc);
|
||||
|
||||
/* Call fcntl(F_GETFL) to get the file open mode. */
|
||||
|
||||
oflags = fcntl(aiocbp->aio_fildes, F_GETFL);
|
||||
@ -151,7 +160,7 @@ static void aio_write_worker(FAR void *arg)
|
||||
|
||||
/* Signal the client */
|
||||
|
||||
(void)aio_signal(aiocbp);
|
||||
(void)aio_signal(pid, aiocbp);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -278,6 +287,7 @@ static void aio_write_worker(FAR void *arg)
|
||||
|
||||
int aio_write(FAR struct aiocb *aiocbp)
|
||||
{
|
||||
FAR struct aio_container_s *aioc;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(aiocbp);
|
||||
@ -287,13 +297,16 @@ int aio_write(FAR struct aiocb *aiocbp)
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
/* Save the ID of the calling, client thread */
|
||||
/* Create a container for the AIO control block. This will not fail but
|
||||
* may cause us to block if there are insufficient resources to satisfy
|
||||
* the request.
|
||||
*/
|
||||
|
||||
aiocbp->aio_pid = getpid();
|
||||
aioc = aio_contain(aiocbp);
|
||||
|
||||
/* Defer the work to the worker thread */
|
||||
|
||||
ret = work_queue(LPWORK, &aiocbp->aio_work, aio_write_worker, aiocbp, 0);
|
||||
ret = work_queue(LPWORK, &aioc->aioc_work, aio_write_worker, aioc, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
aiocbp->aio_result = ret;
|
||||
|
Loading…
Reference in New Issue
Block a user