コード例 #1
0
ファイル: LinuxSocket.cs プロジェクト: UCIS/UCIS.Core
        void TryAsyncIO(AsyncIOResult ar, Boolean sync)
        {
            int read;

            if (handle == -1)
            {
                AsyncIOSetCompleted(ar, sync, new ObjectDisposedException(objectname));
                return;
            }
            if (ar.Operation == 1)
            {
                read = send(handle, ref ar.Buffer[ar.Offset], (UIntPtr)ar.Length, ar.Flags);
            }
            else if (ar.Operation == 2)
            {
                Boolean wasBlocking = Blocking;
                Blocking = false;
                read     = accept4(handle, IntPtr.Zero, IntPtr.Zero, 0x80000);
                var err = read == -1 ? Marshal.GetLastWin32Error() : 0;
                Blocking = wasBlocking;
                if (read != -1)
                {
                    ar.Transferred = read;
                    AsyncIOSetCompleted(ar, sync, null);
                }
                else if (err != 11)
                {
                    AsyncIOSetCompleted(ar, sync, new PosixException(err, "accept4"));
                }
                return;
            }
            else
            {
                read = recv(handle, ref ar.Buffer[ar.Offset], (UIntPtr)ar.Length, ar.Flags);
                if (read == 0 && ar.Operation == 0)
                {
                    AsyncIOSetCompleted(ar, sync, null);
                    return;
                }
            }
            if (read == -1 && Marshal.GetLastWin32Error() == 11)
            {
                read = 0;
            }
            if (read < 0)
            {
                AsyncIOSetCompleted(ar, sync, new PosixException(ar.Operation == 1 ? "send" : "recv"));
            }
            else
            {
                ar.Offset      += read;
                ar.Length      -= read;
                ar.Transferred += read;
                if (ar.Length <= 0 || (ar.Transferred > 0 && ar.Operation == 0))
                {
                    AsyncIOSetCompleted(ar, sync, null);
                }
            }
        }
コード例 #2
0
ファイル: LinuxSocket.cs プロジェクト: UCIS/UCIS.Core
        void AsyncIOSetCompleted(AsyncIOResult ar, Boolean synchronous, Exception error)
        {
            AsyncIOResult call = null;

            lock (this) {
                if (ar.Operation == 1)
                {
                    if (sendqhead == ar)
                    {
                        sendqhead = call = ar.Next;
                    }
                    if (sendqtail == ar)
                    {
                        sendqtail = null;
                    }
                }
                else
                {
                    if (recvqhead == ar)
                    {
                        recvqhead = call = ar.Next;
                    }
                    if (recvqtail == ar)
                    {
                        recvqtail = null;
                    }
                }
                ar.Next = null;
            }
            ar.SetCompleted(synchronous, error);
            if (call != null)
            {
                TryAsyncIO(call, false);
                if (!call.IsCompleted)
                {
                    EpollWait();                                    //request was queued while this one was completing (synchronously, possibly chained)
                }
            }
        }
コード例 #3
0
ファイル: LinuxSocket.cs プロジェクト: UCIS/UCIS.Core
        IAsyncResult BeginAsyncIO(int op, byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0 || size < 0 || offset + size > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (handle == -1)
            {
                throw new ObjectDisposedException(objectname);
            }
            AsyncIOResult ar = new AsyncIOResult(callback, state)
            {
                Socket    = this,
                Buffer    = buffer,
                Offset    = offset,
                Length    = size,
                Flags     = ConvertFlags(socketFlags) | 0x40,             //flags | MSG_DONTWAIT
                Operation = op,
            };
            Boolean first = false;

            lock (this) {
                if (op == 1)
                {
                    if (sendqtail == null)
                    {
                        first          = true;
                        sendqhead      = ar;
                        asyncwritebusy = 1;
                    }
                    else
                    {
                        sendqtail.Next = ar;
                    }
                    sendqtail = ar;
                }
                else
                {
                    if (recvqtail == null)
                    {
                        first         = true;
                        recvqhead     = ar;
                        asyncreadbusy = 1;
                    }
                    else
                    {
                        recvqtail.Next = ar;
                    }
                    recvqtail = ar;
                }
            }
            if (first)
            {
                TryAsyncIO(ar, true);
                if (op == 1)
                {
                    asyncwritebusy = 0;
                }
                else
                {
                    asyncreadbusy = 0;
                }
                if (!ar.IsCompleted || ar.Next != null)
                {
                    EpollWait();
                }
            }
            return(ar);
        }