summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/aio_cancel.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/posix/src/aio_cancel.c')
-rw-r--r--cpukit/posix/src/aio_cancel.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/cpukit/posix/src/aio_cancel.c b/cpukit/posix/src/aio_cancel.c
new file mode 100644
index 0000000000..56b7b01079
--- /dev/null
+++ b/cpukit/posix/src/aio_cancel.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <aio.h>
+#include <rtems/posix/aio_misc.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <rtems/system.h>
+#include <rtems/seterr.h>
+
+/*
+ * aio_cancel
+ *
+ * Cancel an asynchronous I/O request
+ *
+ * Input parameters:
+ * fildes - file descriptor
+ * aiocbp - asynchronous I/O control block
+ *
+ * Output parameters:
+ * AIO_CANCELED - if the requested operation(s)
+ * were canceled
+ * AIO_NOTCANCELED - if at least one of the requested
+ * operation(s) cannot be canceled
+ */
+
+
+int aio_cancel(int fildes, struct aiocb *aiocbp)
+{
+ rtems_aio_request_chain *r_chain;
+ int result;
+
+ pthread_mutex_lock (&aio_request_queue.mutex);
+
+ if (fcntl (fildes, F_GETFD) < 0) {
+ pthread_mutex_unlock(&aio_request_queue.mutex);
+ rtems_set_errno_and_return_minus_one (EBADF);
+ }
+
+ /* if aiocbp is NULL remove all request for given file descriptor */
+ if (aiocbp == NULL) {
+ AIO_printf ("Cancel all requests\n");
+
+ r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, fildes, 0);
+ if (r_chain == NULL) {
+ AIO_printf ("Request chain not on [WQ]\n");
+
+ if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) {
+ r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0);
+ if (r_chain == NULL) {
+ pthread_mutex_unlock(&aio_request_queue.mutex);
+ return AIO_ALLDONE;
+ }
+
+ AIO_printf ("Request chain on [IQ]\n");
+
+ rtems_chain_extract (&r_chain->next_fd);
+ rtems_aio_remove_fd (r_chain);
+ pthread_mutex_destroy (&r_chain->mutex);
+ pthread_cond_destroy (&r_chain->mutex);
+ free (r_chain);
+
+ pthread_mutex_unlock (&aio_request_queue.mutex);
+ return AIO_CANCELED;
+ }
+
+ pthread_mutex_unlock (&aio_request_queue.mutex);
+ return AIO_ALLDONE;
+ }
+
+ AIO_printf ("Request chain on [WQ]\n");
+
+ pthread_mutex_lock (&r_chain->mutex);
+ rtems_chain_extract (&r_chain->next_fd);
+ rtems_aio_remove_fd (r_chain);
+ pthread_mutex_unlock (&r_chain->mutex);
+ pthread_mutex_unlock (&aio_request_queue.mutex);
+ return AIO_CANCELED;
+ } else {
+ AIO_printf ("Cancel request\n");
+
+ if (aiocbp->aio_fildes != fildes) {
+ pthread_mutex_unlock (&aio_request_queue.mutex);
+ rtems_set_errno_and_return_minus_one (EINVAL);
+ }
+
+ r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, fildes, 0);
+ if (r_chain == NULL) {
+ if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) {
+ r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0);
+ if (r_chain == NULL) {
+ pthread_mutex_unlock (&aio_request_queue.mutex);
+ rtems_set_errno_and_return_minus_one (EINVAL);
+ }
+
+ AIO_printf ("Request on [IQ]\n");
+
+ result = rtems_aio_remove_req (&r_chain->perfd, aiocbp);
+ pthread_mutex_unlock (&aio_request_queue.mutex);
+ return result;
+ } else {
+ pthread_mutex_unlock (&aio_request_queue.mutex);
+ return AIO_ALLDONE;
+ }
+ }
+ AIO_printf ("Request on [WQ]\n");
+
+ pthread_mutex_lock (&r_chain->mutex);
+ result = rtems_aio_remove_req (&r_chain->perfd, aiocbp);
+ pthread_mutex_unlock (&r_chain->mutex);
+ pthread_mutex_unlock (&aio_request_queue.mutex);
+ return result;
+ }
+ return AIO_ALLDONE;
+}