public unsafe static PosixResult IoSubmit(aio_context_t ctx, int nr, iocb **iocbpp) { int rv = io_submit(ctx, nr, iocbpp); return(PosixResult.FromReturnValue(rv)); }
public unsafe bool ExecuteOperations() { List <Operation>?scheduled = _scheduledOperations; if (scheduled == null) { return(false); } _scheduledOperations = _cachedOperationsList; _cachedOperationsList = null; if (_results == null || _results.Length < scheduled.Count) { _results = new AsyncOperationResult[Math.Max(scheduled.Count, 2 * (_results?.Length ?? 0))]; } AsyncOperationResult[] results = _results; int queueLength = scheduled.Count; int queueOffset = 0; while (queueOffset < queueLength) { int nr = Math.Min((queueLength - queueOffset), IocbLength); try { iocb *aioCbs = AioCbs; for (int i = queueOffset; i < (queueOffset + nr); i++) { Operation op = scheduled[i]; int fd = op.Handle.DangerousGetHandle().ToInt32(); // TODO: make safe MemoryHandle handle = op.Memory.Pin(); _memoryHandles.Add(handle); aioCbs->aio_fildes = fd; aioCbs->aio_data = (ulong)i; aioCbs->aio_lio_opcode = op.IsReadNotWrite ? IOCB_CMD_PREAD : IOCB_CMD_PWRITE; aioCbs->aio_buf = (ulong)handle.Pointer; aioCbs->aio_nbytes = (ulong)op.Memory.Length; aioCbs++; } iocb **iocbpp = AioCbsTable; int toSubmit = nr; while (toSubmit > 0) { int rv = io_submit(_ctx, toSubmit, iocbpp); if (rv == -1) { PlatformException.Throw(); } int toReceive = rv; toSubmit -= rv; iocbpp += rv; while (toReceive > 0) { do { rv = IoGetEvents(_ctx, toReceive, AioEvents); } while (rv == -1 && errno == EINTR); if (rv == -1) { PlatformException.Throw(); } io_event *events = AioEvents; for (int i = 0; i < rv; i++) { results[(int)events->data] = new AsyncOperationResult(events->res); events++; } toReceive -= rv; } } } finally { foreach (var handle in _memoryHandles) { handle.Dispose(); } _memoryHandles.Clear(); } // Callbacks for (int i = queueOffset; i < (queueOffset + nr); i++) { Operation op = scheduled[i]; op.Callback(results[i], op.State, op.Data); } queueOffset += nr; } scheduled.Clear(); if (_scheduledOperations == null) { _scheduledOperations = scheduled; return(false); } else { _cachedOperationsList = scheduled; return(_scheduledOperations.Count > 0); } }
public static int io_submit(aio_context_t ctx, long_t nr, iocb **iocbpp) { int rv = (int)syscall(SYS_io_submit, ctx.ring, nr, iocbpp); return(rv); }