예제 #1
0
        // TODO: Has close() race condition.
        public unsafe override void Write(byte[] buffer, int offset, int count)
        {
            Throw.If.OutOfRange(buffer, offset, count);
            UpdateSettings();
            if (count == 0)
            {
                return;
            }

            fixed(byte *buffer0 = buffer)
            {
                int startTime = Environment.TickCount, writeTimeout = WriteTimeout;

                for (int bytesWritten = 0; bytesWritten < count;)
                {
                    int handle = _handle;
                    if (handle < 0)
                    {
                        throw new IOException("Closed.");
                    }

                    var bufferPtr    = (IntPtr)(buffer0 + offset + bytesWritten);
                    int bytesToWrite = count - bytesWritten;

                    var fd = new NativeMethods.pollfd()
                    {
                        fd = handle, events = NativeMethods.pollev.OUT
                    };
                    int ret = NativeMethods.retry(() => NativeMethods.poll(ref fd, 1, GetTimeout(startTime, writeTimeout)));
                    if (ret < 0)
                    {
                        throw new IOException("Write failed (poll).");
                    }
                    if (ret == 1)
                    {
                        if (fd.revents != NativeMethods.pollev.OUT)
                        {
                            throw new IOException(string.Format("Closed during write ({0}).", fd.revents));
                        }

                        int writeCount = checked ((int)NativeMethods.retry(() => NativeMethods.write(handle, bufferPtr, (UIntPtr)bytesToWrite)));
                        if (writeCount <= 0 || writeCount > bytesToWrite)
                        {
                            throw new IOException("Write failed.");
                        }
                        bytesWritten += writeCount;
                    }
                }
            }
        }
예제 #2
0
        // TODO: Has close() race condition.
        public unsafe override int Read(byte[] buffer, int offset, int count)
        {
            Throw.If.OutOfRange(buffer, offset, count);
            UpdateSettings();
            if (count == 0)
            {
                return(0);
            }

            fixed(byte *buffer0 = buffer)
            {
                int startTime = Environment.TickCount, readTimeout = ReadTimeout;

                while (true)
                {
                    int handle = _handle;
                    if (handle < 0)
                    {
                        throw new IOException("Closed.");
                    }

                    var bufferPtr   = (IntPtr)(buffer0 + offset);
                    int bytesToRead = count;

                    var fd = new NativeMethods.pollfd()
                    {
                        fd = handle, events = NativeMethods.pollev.IN
                    };
                    int ret = NativeMethods.retry(() => NativeMethods.poll(ref fd, 1, GetTimeout(startTime, readTimeout)));
                    if (ret < 0)
                    {
                        throw new IOException("Read failed (poll).");
                    }
                    if (ret == 1)
                    {
                        if (fd.revents != NativeMethods.pollev.IN)
                        {
                            throw new IOException(string.Format("Closed during read ({0}).", fd.revents));
                        }

                        int readCount = checked ((int)NativeMethods.retry(() => NativeMethods.read(handle, bufferPtr, (UIntPtr)bytesToRead)));
                        if (readCount <= 0 || readCount > bytesToRead)
                        {
                            throw new IOException("Read failed.");
                        }
                        return(readCount);
                    }
                }
            }
        }