Beispiel #1
0
        void OnReadUnix(UVBuffer.Unix buffer, IntPtr bytesAvaliable)
        {
            long bytesRead = bytesAvaliable.ToInt64();

            if (bytesRead == 0)
            {
                return;
            }
            else if (bytesRead < 0)
            {
                var error = UVException.ErrorCodeToError((int)bytesRead);
                if (error == UVError.EOF)
                {
                    OnEndOfStream();
                    Dispose();
                }
                else
                {
                    Dispose();
                    throw new UVException((int)bytesRead);
                }
            }
            else
            {
                using (var owned = new OwnedNativeBuffer((int)bytesRead, buffer.Buffer)) {
                    OnReadCompleted(owned.Memory);
                    //buffer.Dispose(); // TODO: owned memory frees the memory. this is bad; need to fix
                }
            }
        }
Beispiel #2
0
        public unsafe void TryWrite(Span <byte> data)
        {
            EnsureNotDisposed();

            ArraySegment <byte> array;
            void * pointer;
            IntPtr ptrData;

            if (data.TryGetArrayElseGetPointer(out array, out pointer))
            {
                throw new NotImplementedException("needs to pin the array");
            }
            else
            {
                ptrData = (IntPtr)pointer;
            }

            if (IsUnix)
            {
                var buffer = new UVBuffer.Unix(ptrData, (uint)data.Length);
                UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
            }
            else
            {
                var buffer = new UVBuffer.Windows(ptrData, (uint)data.Length);
                UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
            }
        }
Beispiel #3
0
        void OnReadUnix(UVBuffer.Unix buffer, IntPtr bytesAvaliable)
        {
            long bytesRead = bytesAvaliable.ToInt64();

            if (bytesRead == 0)
            {
                return;
            }
            else if (bytesRead < 0)
            {
                var error = UVException.ErrorCodeToError((int)bytesRead);
                if (error == UVError.EOF)
                {
                    OnEndOfStream();
                    Dispose();
                }
                else
                {
                    Dispose();
                    throw new UVException((int)bytesRead);
                }
            }
            else
            {
                // This can be a Span<byte> but the samples pass it directly to TryWrite which
                // needs to unpack the data and turn it back into either an array or native memory
                var readSlice = new UnsafeMemory <byte>((byte *)buffer.Buffer, (int)bytesRead);
                OnReadCompleted(readSlice);
                buffer.Dispose();
            }
        }
Beispiel #4
0
        void OnReadUnix(UVBuffer.Unix buffer, IntPtr bytesAvaliable)
        {
            long bytesRead = bytesAvaliable.ToInt64();

            if (bytesRead == 0)
            {
                return;
            }
            else if (bytesRead < 0)
            {
                var error = UVException.ErrorCodeToError((int)bytesRead);
                if (error == UVError.EOF)
                {
                    OnEndOfStream();
                    Dispose();
                }
                else
                {
                    Dispose();
                    throw new UVException((int)bytesRead);
                }
            }
            else
            {
                var readSlice = new Span <byte>((byte *)buffer.Buffer, (int)bytesRead);
                OnReadCompleted(readSlice);
                buffer.Dispose();
            }
        }
Beispiel #5
0
        void OnReadWindows(UVBuffer.Windows buffer, IntPtr bytesAvaliable)
        {
            // TODO: all branches need to release buffer, I think
            long bytesRead = bytesAvaliable.ToInt64();

            if (bytesRead == 0)
            {
                buffer.Dispose();
                return;
            }
            else if (bytesRead < 0)
            {
                var error = UVException.ErrorCodeToError((int)bytesRead);
                if (error == UVError.EOF)
                {
                    OnEndOfStream();
                    Dispose();
                    buffer.Dispose();
                }
                else
                {
                    Dispose();
                    buffer.Dispose();
                    throw new UVException((int)bytesRead);
                }
            }
            else
            {
                var readSlice = new ByteSpan((byte *)buffer.Buffer, (int)bytesRead);
                OnReadCompleted(readSlice);
                buffer.Dispose();
            }
        }
Beispiel #6
0
        public unsafe void TryWrite(byte[] data, int length)
        {
            Debug.Assert(data != null);
            if (data.Length < length)
            {
                throw new ArgumentOutOfRangeException("length");
            }

            EnsureNotDisposed();

            fixed(byte *pData = data)
            {
                IntPtr ptrData = (IntPtr)pData;

                if (IsUnix)
                {
                    var buffer = new UVBuffer.Unix(ptrData, (uint)length);
                    UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
                }
                else
                {
                    var buffer = new UVBuffer.Windows(ptrData, (uint)length);
                    UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
                }
            }
        }
Beispiel #7
0
        public unsafe void TryWrite(Memory <byte> data)
        {
            // This can work with Span<byte> because it's synchronous but we need pinning support
            EnsureNotDisposed();

            void *pointer;

            if (!data.TryGetPointer(out pointer))
            {
                throw new InvalidOperationException("Pointer not available");
            }

            IntPtr ptrData = (IntPtr)pointer;
            var    length  = data.Length;

            if (IsUnix)
            {
                var buffer = new UVBuffer.Unix(ptrData, (uint)length);
                UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
            }
            else
            {
                var buffer = new UVBuffer.Windows(ptrData, (uint)length);
                UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
            }
        }
Beispiel #8
0
        static sockaddr_in6 CreateSockaddrIp6(string ip, int port)
        {
            sockaddr_in6 address;
            int          result = UVInterop.uv_ip6_addr(ip, port, out address);

            UVException.ThrowIfError(result);
            return(address);
        }
Beispiel #9
0
        public UVLoop()
        {
            _pool = UVBuffer.Default;
            var size       = UVInterop.uv_loop_size().ToInt32();
            var loopHandle = Marshal.AllocHGlobal(size); // this needs to be deallocated

            UVException.ThrowIfError(UVInterop.uv_loop_init(loopHandle));
            _handle = loopHandle;
        }
Beispiel #10
0
 static void Bind(TcpListener listener, string ipAddress, int port, bool ip6 = false, bool dualstack = false)
 {
     if (ip6)
     {
         sockaddr_in6 address = CreateSockaddrIp6(ipAddress.ToString(), port);
         UVException.ThrowIfError(UVInterop.uv_tcp_bind(listener.Handle, ref address, (uint)(dualstack ? 0 : 1)));
     }
     else
     {
         sockaddr_in address = CreateSockaddr(ipAddress.ToString(), port);
         UVException.ThrowIfError(UVInterop.uv_tcp_bind(listener.Handle, ref address, 0));
     }
 }
Beispiel #11
0
        public void ReadStart()
        {
            EnsureNotDisposed();

            if (IsUnix)
            {
                UVException.ThrowIfError(UVInterop.uv_read_start(Handle, UVBuffer.AllocateUnixBuffer, ReadUnix));
            }
            else
            {
                UVException.ThrowIfError(UVInterop.uv_read_start(Handle, UVBuffer.AllocWindowsBuffer, ReadWindows));
            }
        }
Beispiel #12
0
        public unsafe void TryWrite(Span <byte> data)
        {
            EnsureNotDisposed();

            IntPtr ptrData = (IntPtr)data.UnsafePointer;

            if (IsUnix)
            {
                var buffer = new UVBuffer.Unix(ptrData, (uint)data.Length);
                UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
            }
            else
            {
                var buffer = new UVBuffer.Windows(ptrData, (uint)data.Length);
                UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
            }
        }
Beispiel #13
0
        void OnReadWindows(UVBuffer.Windows buffer, IntPtr bytesAvaliable)
        {
            // TODO: all branches need to release buffer, I think
            long bytesRead = bytesAvaliable.ToInt64();

            if (bytesRead == 0)
            {
                buffer.Dispose();
                return;
            }
            else if (bytesRead < 0)
            {
                var error = UVException.ErrorCodeToError((int)bytesRead);
                if (error == UVError.EOF)
                {
                    OnEndOfStream();
                    Dispose();
                    buffer.Dispose();
                }
                else if (error == UVError.ECONNRESET)
                {
                    Debug.Assert(buffer.Buffer == IntPtr.Zero && buffer.Length == 0);
                    // no need to dispose
                    // TODO: what should we do here?
                }
                else
                {
                    Dispose();
                    buffer.Dispose();
                    throw new UVException((int)bytesRead);
                }
            }
            else
            {
                using (var owned = new OwnedNativeBuffer((int)bytesRead, buffer.Buffer))
                {
                    OnReadCompleted(owned.Memory);
                    //buffer.Dispose(); // TODO: owned memory frees the memory. this is bad; need to fix
                }
            }
        }
Beispiel #14
0
        public unsafe void TryWrite(ReadOnlySpan <byte> data)
        {
            // This can work with Span<byte> because it's synchronous but we need pinning support
            EnsureNotDisposed();

            fixed(byte *source = &MemoryMarshal.GetReference(data))
            {
                var length = data.Length;

                if (IsUnix)
                {
                    var buffer = new UVBuffer.Unix((IntPtr)source, (uint)length);
                    UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
                }
                else
                {
                    var buffer = new UVBuffer.Windows((IntPtr)source, (uint)length);
                    UVException.ThrowIfError(UVInterop.uv_try_write(Handle, &buffer, 1));
                }
            }
        }
Beispiel #15
0
        void OnReadWindows(UVBuffer.Windows buffer, IntPtr bytesAvaliable)
        {
            // TODO: all branches need to release buffer, I think
            long bytesRead = bytesAvaliable.ToInt64();

            if (bytesRead == 0)
            {
                buffer.Dispose();
                return;
            }
            else if (bytesRead < 0)
            {
                var error = UVException.ErrorCodeToError((int)bytesRead);
                if (error == UVError.EOF)
                {
                    OnEndOfStream();
                    Dispose();
                    buffer.Dispose();
                }
                else if (error == UVError.ECONNRESET)
                {
                    Debug.Assert(buffer.Buffer == IntPtr.Zero && buffer.Length == 0);
                    // no need to dispose
                    // TODO: what should we do here?
                }
                else
                {
                    Dispose();
                    buffer.Dispose();
                    throw new UVException((int)bytesRead);
                }
            }
            else
            {
                var readSlice = new Span <byte>((byte *)buffer.Buffer, (int)bytesRead);
                OnReadCompleted(readSlice);
                buffer.Dispose();
            }
        }
Beispiel #16
0
        static void OnNotified(IntPtr handle, int status)
        {
            var listener = As <UVListener <TStream> >(handle);

            var stream     = listener.CreateStream();
            var connection = stream as TStream;

            try
            {
                UVException.ThrowIfError(UVInterop.uv_accept(listener.Handle, connection.Handle));
            }
            catch (Exception e)
            {
                stream.Dispose();
                connection.Dispose();
                Environment.FailFast(e.ToString());
            }

            if (listener.ConnectionAccepted != null)
            {
                listener.ConnectionAccepted(connection);
            }
        }
Beispiel #17
0
 public TcpListener(string ipAddress, int port, UVLoop loop) : base(loop, HandleType.UV_TCP)
 {
     UVException.ThrowIfError(UVInterop.uv_tcp_init(Loop.Handle, Handle));
     Bind(this, ipAddress, port);
 }