/*
- * Copyright (c) 2003-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <mach/mach_types.h>
#include <kern/kern_types.h>
+#include <kern/waitq.h>
#include <kern/zalloc.h>
#include <kern/task.h>
#include <kern/sched_prim.h>
TAILQ_HEAD(, aio_workq_entry) aioq_entries;
int aioq_count;
lck_mtx_t aioq_mtx;
- wait_queue_t aioq_waitq;
+ struct waitq aioq_waitq;
} *aio_workq_t;
#define AIO_NUM_WORK_QUEUES 1
TAILQ_INIT(&wq->aioq_entries);
wq->aioq_count = 0;
lck_mtx_init(&wq->aioq_mtx, aio_queue_lock_grp, aio_lock_attr);
- wq->aioq_waitq = wait_queue_alloc(SYNC_POLICY_FIFO);
+ waitq_init(&wq->aioq_waitq, SYNC_POLICY_FIFO|SYNC_POLICY_DISABLE_IRQ);
}
(int)p, fd, 0, 0, 0 );
while (aio_proc_active_requests_for_file(p, fd) > 0) {
- msleep(&p->AIO_CLEANUP_SLEEP_CHAN, aio_proc_mutex(p), PRIBIO | PDROP, "aio_close", 0 );
+ msleep(&p->AIO_CLEANUP_SLEEP_CHAN, aio_proc_mutex(p), PRIBIO, "aio_close", 0 );
}
- } else {
- aio_proc_unlock(p);
}
-
-
+
+ aio_proc_unlock(p);
+
KERNEL_DEBUG( (BSDDBG_CODE(DBG_BSD_AIO, AIO_close)) | DBG_FUNC_END,
(int)p, fd, 0, 0, 0 );
*/
error = msleep1(&p->AIO_SUSPEND_SLEEP_CHAN, aio_proc_mutex(p), PCATCH | PWAIT | PDROP, "aio_suspend", abstime); /* XXX better priority? */
- if ( error == THREAD_AWAKENED ) {
+ if ( error == 0 ) {
/*
* got our wakeup call from aio_work_thread().
* Since we can get a wakeup on this channel from another thread in the
*/
goto check_for_our_aiocbp;
}
- else if ( error == THREAD_TIMED_OUT ) {
+ else if ( error == EWOULDBLOCK ) {
/* our timeout expired */
error = EAGAIN;
}
/* And work queue */
aio_workq_lock_spin(queue);
aio_workq_add_entry_locked(queue, entryp);
- wait_queue_wakeup_one(queue->aioq_waitq, queue, THREAD_AWAKENED);
+ waitq_wakeup64_one(&queue->aioq_waitq, CAST_EVENT64_T(queue),
+ THREAD_AWAKENED, WAITQ_ALL_PRIORITIES);
aio_workq_unlock(queue);
if (proc_locked == 0) {
nowork:
/* We will wake up when someone enqueues something */
- wait_queue_assert_wait(queue->aioq_waitq, queue, THREAD_UNINT, 0);
+ waitq_assert_wait64(&queue->aioq_waitq, CAST_EVENT64_T(queue), THREAD_UNINT, 0);
aio_workq_unlock(queue);
thread_block( (thread_continue_t)aio_work_thread );
/* do some more validation on the aiocb and embedded file descriptor */
result = aio_validate( entryp );
+ if ( result != 0 )
+ goto error_exit_with_ref;
+ /* get a reference on the current_thread, which is passed in vfs_context. */
+ entryp->thread = current_thread();
+ thread_reference( entryp->thread );
+ return ( entryp );
+
+error_exit_with_ref:
+ if ( VM_MAP_NULL != entryp->aio_map ) {
+ vm_map_deallocate( entryp->aio_map );
+ }
error_exit:
if ( result && entryp != NULL ) {
zfree( aio_workq_zonep, entryp );
vm_map_deallocate(entryp->aio_map);
}
+ /* remove our reference to thread which enqueued the request */
+ if ( NULL != entryp->thread ) {
+ thread_deallocate( entryp->thread );
+ }
+
entryp->aio_refcount = -1; /* A bit of poisoning in case of bad refcounting. */
zfree( aio_workq_zonep, entryp );
/* we don't have read or write access */
result = EBADF;
}
- else if ( fp->f_fglob->fg_type != DTYPE_VNODE ) {
+ else if ( FILEGLOB_DTYPE(fp->f_fglob) != DTYPE_VNODE ) {
/* this is not a file */
result = ESPIPE;
} else
return(EBADF);
}
- /*
- * <rdar://4714366>
- * Needs vfs_context_t from vfs_context_create() in entryp!
- */
- context.vc_thread = proc_thread(entryp->procp); /* XXX */
+ context.vc_thread = entryp->thread; /* XXX */
context.vc_ucred = fp->f_fglob->fg_cred;
error = dofileread(&context, fp,
flags |= FOF_OFFSET;
}
- /*
- * <rdar://4714366>
- * Needs vfs_context_t from vfs_context_create() in entryp!
- */
- context.vc_thread = proc_thread(entryp->procp); /* XXX */
+ context.vc_thread = entryp->thread; /* XXX */
context.vc_ucred = fp->f_fglob->fg_cred;
/* NB: tell dofilewrite the offset, and to use the proc cred */
entryp->aiocb.aio_offset,
flags,
&entryp->returnval);
-
- fp_drop(entryp->procp, entryp->aiocb.aio_fildes, fp, 0);
+
+ if (entryp->returnval)
+ fp_drop_written(entryp->procp, entryp->aiocb.aio_fildes, fp);
+ else
+ fp_drop(entryp->procp, entryp->aiocb.aio_fildes, fp, 0);
return( error );