예제 #1
0
        internal Task Ensure(int count, bool async, bool dontBreakOnTimeouts)
        {
            return(count <= ReadBytesLeft ? PGUtil.CompletedTask : EnsureLong());

            async Task EnsureLong()
            {
                Debug.Assert(count <= Size);
                Debug.Assert(count > ReadBytesLeft);
                count -= ReadBytesLeft;
                if (count <= 0)
                {
                    return;
                }

                if (ReadPosition == FilledBytes)
                {
                    Clear();
                }
                else if (count > Size - FilledBytes)
                {
                    Array.Copy(Buffer, ReadPosition, Buffer, 0, ReadBytesLeft);
                    FilledBytes  = ReadBytesLeft;
                    ReadPosition = 0;
                }

                try
                {
                    while (count > 0)
                    {
                        var toRead = Size - FilledBytes;

                        int read;
                        if (async)
                        {
                            if (AwaitableSocket == null)  // SSL
                            {
                                read = await Underlying.ReadAsync(Buffer, FilledBytes, toRead);
                            }
                            else  // Non-SSL async I/O, optimized
                            {
                                AwaitableSocket.SetBuffer(Buffer, FilledBytes, toRead);
                                await AwaitableSocket.ReceiveAsync();

                                read = AwaitableSocket.BytesTransferred;
                            }
                        }
                        else    // Sync I/O
                        {
                            read = Underlying.Read(Buffer, FilledBytes, toRead);
                        }

                        if (read == 0)
                        {
                            throw new EndOfStreamException();
                        }
                        count       -= read;
                        FilledBytes += read;
                    }
                }
                // We have a special case when reading async notifications - a timeout may be normal
                // shouldn't be fatal
                // Note that mono throws SocketException with the wrong error (see #1330)
                catch (IOException e) when(
                    dontBreakOnTimeouts && (e.InnerException as SocketException)?.SocketErrorCode ==
                    (Type.GetType("Mono.Runtime") == null ? SocketError.TimedOut : SocketError.WouldBlock)
                    )
                {
                    throw new TimeoutException("Timeout while reading from stream");
                }
                catch (Exception e)
                {
                    Connector.Break();
                    throw new NpgsqlException("Exception while reading from stream", e);
                }
            }
        }
예제 #2
0
        public async Task Flush(bool async)
        {
            if (_copyMode)
            {
                // In copy mode, we write CopyData messages. The message code has already been
                // written to the beginning of the buffer, but we need to go back and write the
                // length.
                if (WritePosition == 1)
                {
                    return;
                }
                var pos = WritePosition;
                WritePosition = 1;
                WriteInt32(pos - 1);
                WritePosition = pos;
            }
            else if (WritePosition == 0)
            {
                return;
            }

            try
            {
                if (async)
                {
                    if (AwaitableSocket == null)  // SSL
                    {
                        await Underlying.WriteAsync(Buffer, 0, WritePosition);
                    }
                    else  // Non-SSL async I/O, optimized
                    {
                        AwaitableSocket.SetBuffer(Buffer, 0, WritePosition);
                        await AwaitableSocket.SendAsync();
                    }
                }
                else  // Sync I/O
                {
                    Underlying.Write(Buffer, 0, WritePosition);
                }
            }
            catch (Exception e)
            {
                Connector.Break();
                throw new NpgsqlException("Exception while writing to stream", e);
            }

            try
            {
                if (async)
                {
                    await Underlying.FlushAsync();
                }
                else
                {
                    Underlying.Flush();
                }
            }
            catch (Exception e)
            {
                Connector.Break();
                throw new NpgsqlException("Exception while flushing stream", e);
            }

            NpgsqlEventSource.Log.BytesWritten(WritePosition);
            //NpgsqlEventSource.Log.RequestFailed();

            WritePosition = 0;
            if (CurrentCommand != null)
            {
                CurrentCommand.FlushOccurred = true;
                CurrentCommand = null;
            }
            if (_copyMode)
            {
                WriteCopyDataHeader();
            }
        }