Beispiel #1
0
        public OverlappedEntry
        (
            nuint?lpCompletionKey           = null,
            Overlapped *lpOverlapped        = null,
            nuint? @internal                = null,
            uint?dwNumberOfBytesTransferred = null
        ) : this()
        {
            if (lpCompletionKey is not null)
            {
                LpCompletionKey = lpCompletionKey.Value;
            }

            if (lpOverlapped is not null)
            {
                LpOverlapped = lpOverlapped;
            }

            if (@internal is not null)
            {
                Internal = @internal.Value;
            }

            if (dwNumberOfBytesTransferred is not null)
            {
                DwNumberOfBytesTransferred = dwNumberOfBytesTransferred.Value;
            }
        }
Beispiel #2
0
        public IOLoop()
        {
            Thread mthread = new Thread(delegate() {
                unsafe
                {
                    while (true)
                    {
                        IntPtr[] handles = null;
                        int count        = -1;
                        lock (ops)
                        {
                            count   = ops.Count;
                            handles = new IntPtr[count + 1];
                            fixed(IntPtr * handles_ptr = handles)
                            {
                                IntPtr *hptr = handles_ptr + 1;
                                handles[0]   = evt.SafeWaitHandle.DangerousGetHandle();
                                for (int i = 0; i < ops.Count; i++)
                                {
                                    hptr[i] = ((Overlapped *)(ops[i].overlapped.AddrOfPinnedObject()))->hEvent;
                                }
                            }
                        }

                        WaitForMultipleObjects(count + 1, handles, false, -1);
                        lock (ops)
                        {
                            List <AsyncIOOperation> toRemove = new List <AsyncIOOperation>();
                            foreach (var iable in ops.ToList()) //Copy list in case callback updates it.
                            {
                                //!= 259
                                Overlapped *olap = (Overlapped *)iable.overlapped.AddrOfPinnedObject();
                                if (olap->Internal.ToInt64() != 259)
                                {
                                    int transferred = olap->InternalHigh.ToInt32();
                                    iable.cb(transferred);
                                    toRemove.Add(iable);
                                    iable.buffy.Free();
                                    iable.bytes.Free();
                                    iable.flags.Free();
                                    iable.overlapped.Free();
                                }
                            }
                            foreach (var iable in toRemove)
                            {
                                ops.Remove(iable);
                            }
                        }
                    }
                }
            });

            mthread.IsBackground = true;
            mthread.Start();
        }
Beispiel #3
0
        private unsafe void CompletionWorkerThreadProc()
        {
            {
                int count;
                do
                {
                    count = Volatile.Read(ref m_completionPortRefCount);
                    if (count < 1)
                    {
                        // Manager disposed before this thread started.
                        return;
                    }
                }while (Interlocked.CompareExchange(ref m_completionPortRefCount, count + 1, comparand: count) != count);
            }

            try
            {
                while (true)
                {
                    FileSystemWin.IOCompletionPortDequeueResult result = FileSystemWin.GetQueuedCompletionStatus(m_completionPort);

                    Contract.Assume(
                        result.Status != FileSystemWin.IOCompletionPortDequeueStatus.CompletionPortClosed,
                        "We terminate all workers before closing the port (otherwise we risk a handle-recycle race).");

                    Contract.Assert(result.Status == FileSystemWin.IOCompletionPortDequeueStatus.Succeeded);

                    if (result.DequeuedOverlapped == null)
                    {
                        // Completion port is being closed; this is a poison message.
                        Contract.Assume(result.CompletionKey == s_queueCloseCompletionKey);
                        break;
                    }

                    // The OVERLAPPED* attached to each packet is unique to each I/O request. It should be one
                    // that we allocated earlier with AllocateOverlapped. We took care to place a request identifier
                    // immediately after the OVERLAPPED, so we can find the completion target.
                    Overlapped *deqeuedOverlapped = result.DequeuedOverlapped;
                    var         taggedOverlapped  = (TaggedOverlapped *)deqeuedOverlapped;

                    ReleaseOvelappedAndQueueCompletionNotification(taggedOverlapped, result.CompletedIO);
                }

                DecrementCompletionPortRefCount();
            }
            catch (Exception ex)
            {
                ExceptionUtilities.FailFast("Catastrophic failure in I/O completion worker", ex);
                throw;
            }
        }
Beispiel #4
0
        /// <inheritdoc/>
        public unsafe void CancelOverlapped(SafeFileHandle handle, Overlapped *overlapped)
        {
            Contract.Requires(!handle.IsInvalid);
            Contract.Requires(overlapped != null);

            TaggedOverlapped *taggedOverlapped = (TaggedOverlapped *)overlapped;

            if (taggedOverlapped->EntryId == TaggedOverlapped.AvailableMarker)
            {
                return;
            }

            // Best effort.
            Analysis.IgnoreResult(FileSystemWin.TryCancelIoWithOverlapped(handle, overlapped, out int _));
        }
Beispiel #5
0
 public void ReceiveAsync(byte[] buffer, int offset, int count, OnIOComplete completionHandler)
 {
     unsafe
     {
         AsyncIOOperation op = new AsyncIOOperation();
         op.overlapped = GCHandle.Alloc(new Overlapped(), GCHandleType.Pinned);
         Overlapped *overlapped = (Overlapped *)op.overlapped.AddrOfPinnedObject();
         overlapped->hEvent = CreateEventW(IntPtr.Zero, true, false, IntPtr.Zero);
         op.buffy           = GCHandle.Alloc(new WSABuf(), GCHandleType.Pinned);
         WSABuf *buffy = (WSABuf *)op.buffy.AddrOfPinnedObject();
         op.bytes   = GCHandle.Alloc(buffer, GCHandleType.Pinned);
         buffy->buf = op.bytes.AddrOfPinnedObject() + offset;
         buffy->len = (uint)count;
         op.flags   = GCHandle.Alloc(0, GCHandleType.Pinned);
         int r = WSARecv(Handle, new IntPtr(buffy), 1, IntPtr.Zero, op.flags.AddrOfPinnedObject(), new IntPtr(overlapped), IntPtr.Zero);
         int a = WSAGetLastError();
         op.fd = Handle;
         op.cb = completionHandler;
         IOLoop.dispatch_loop.Post(op);
     }
 }
Beispiel #6
0
 /// <inheritdoc />
 public unsafe void Cancel(Overlapped *overlapped) => m_ioCompletionManager.CancelOverlapped(m_handle, overlapped);
Beispiel #7
0
 /// <inheritdoc />
 public unsafe void Cancel(Overlapped *overlapped) => throw new NotImplementedException();
Beispiel #8
0
 public static unsafe extern int WriteFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, uint *lpNumberOfBytesWritten, Overlapped *lpOverlapped);
Beispiel #9
0
 public static unsafe extern int ReadFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToRead, uint *nNumberOfReadBytes, Overlapped *lpOverlapped);