Ejemplo n.º 1
0
        public unsafe static PosixResult IoSubmit(aio_context_t ctx, int nr, iocb **iocbpp)
        {
            int rv = io_submit(ctx, nr, iocbpp);

            return(PosixResult.FromReturnValue(rv));
        }
Ejemplo n.º 2
0
            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);
                }
            }
Ejemplo n.º 3
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);
        }