// 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; } } } }