예제 #1
0
        /// <summary>
        /// Acquires a lease on a safe handle. The lease increments the reference count of the <see cref="SafeHandle"/>
        /// to ensure the handle is not released prior to the lease being released.
        /// </summary>
        /// <remarks>
        /// This method is intended to be used in the initializer of a <c>using</c> statement. Failing to release the
        /// lease will permanently prevent the underlying <see cref="SafeHandle"/> from being released by the garbage
        /// collector.
        /// </remarks>
        /// <param name="handle">The <see cref="SafeHandle"/> to lease.</param>
        /// <returns>A <see cref="SafeHandleLease"/>, which must be disposed to release the resource.</returns>
        /// <exception cref="ObjectDisposedException">If the lease could not be acquired.</exception>
        public static SafeHandleLease Lease(this SafeHandle handle)
        {
            if (handle is null)
            {
                throw new ArgumentNullException(nameof(handle));
            }

            var success = false;

            try
            {
                handle.DangerousAddRef(ref success);
                Debug.Assert(success, $"'{nameof(SafeHandle.DangerousAddRef)}' does not return when '{nameof(success)}' is false.");

                return(new SafeHandleLease(handle));
            }
            catch
            {
                if (success)
                {
                    handle.DangerousRelease();
                }

                throw;
            }
        }
예제 #2
0
        public static SafeHandleLease Lease(this SafeHandle handle)
        {
            RoslynDebug.AssertNotNull(handle);

            var success = false;

            try
            {
                handle.DangerousAddRef(ref success);
                if (!success)
                {
                    throw new ObjectDisposedException(handle.GetType().FullName);
                }

                return(new SafeHandleLease(handle));
            }
            catch
            {
                if (success)
                {
                    handle.DangerousRelease();
                }

                throw;
            }
        }
예제 #3
0
        /// <summary>
        /// Polls a File Descriptor for the passed in flags.
        /// </summary>
        /// <param name="fd">The descriptor to poll</param>
        /// <param name="events">The events to poll for</param>
        /// <param name="timeout">The amount of time to wait; -1 for infinite, 0 for immediate return, and a positive number is the number of milliseconds</param>
        /// <param name="triggered">The events that were returned by the poll call. May be PollEvents.POLLNONE in the case of a timeout.</param>
        /// <returns>An error or Error.SUCCESS.</returns>
        internal static unsafe Error Poll(SafeHandle fd, PollEvents events, int timeout, out PollEvents triggered)
        {
            bool gotRef = false;
            try
            {
                fd.DangerousAddRef(ref gotRef);

                var pollEvent = new PollEvent
                {
                    FileDescriptor = fd.DangerousGetHandle().ToInt32(),
                    Events = events,
                };

                uint unused;
                Error err = Poll(&pollEvent, 1, timeout, &unused);
                triggered = pollEvent.TriggeredEvents;
                return err;
            }
            finally
            {
                if (gotRef)
                {
                    fd.DangerousRelease();
                }
            }
        }
        public static unsafe PosixResult Read(SafeHandle handle, byte *buf, int count)
        {
            bool addedRef = false;

            try
            {
                handle.DangerousAddRef(ref addedRef);

                int     fd = handle.DangerousGetHandle().ToInt32();
                ssize_t rv;
                do
                {
                    rv = read(fd, buf, count);
                } while (rv < 0 && errno == EINTR);

                return(PosixResult.FromReturnValue(rv));
            }
            finally
            {
                if (addedRef)
                {
                    handle.DangerousRelease();
                }
            }
        }
예제 #5
0
 internal static unsafe Error SetIPv4MulticastOption(SafeHandle socket, MulticastOption multicastOption, IPv4MulticastOption* option)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousSetIPv4MulticastOption((int)socket.DangerousGetHandle(), multicastOption, option);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #6
0
 internal static unsafe Error GetBytesAvailable(SafeHandle socket, int* available)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousGetBytesAvailable((int)socket.DangerousGetHandle(), available);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #7
0
 internal static unsafe Error GetSocketErrorOption(SafeHandle socket, Error* socketError)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousGetSocketErrorOption((int)socket.DangerousGetHandle(), socketError);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #8
0
 internal static unsafe Error SendMessage(SafeHandle socket, MessageHeader* messageHeader, SocketFlags flags, long* sent)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousSendMessage((int)socket.DangerousGetHandle(), messageHeader, flags, sent);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #9
0
 internal static unsafe Error SetSockOpt(SafeHandle socket, SocketOptionLevel optionLevel, SocketOptionName optionName, byte* optionValue, int optionLen)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousSetSockOpt((int)socket.DangerousGetHandle(), optionLevel, optionName, optionValue, optionLen);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #10
0
 internal static unsafe Error GetSockName(SafeHandle socket, byte* socketAddress, int* socketAddressLen)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousGetSockName((int)socket.DangerousGetHandle(), socketAddress, socketAddressLen);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #11
0
 internal static unsafe Error SetReceiveTimeout(SafeHandle socket, int millisecondsTimeout)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousSetReceiveTimeout((int)socket.DangerousGetHandle(), millisecondsTimeout);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #12
0
 internal static Error Shutdown(SafeHandle socket, SocketShutdown how)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousShutdown((int)socket.DangerousGetHandle(), how);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #13
0
 internal static Error TryChangeSocketEventRegistration(int port, SafeHandle socket, SocketEvents currentEvents, SocketEvents newEvents, IntPtr data)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousTryChangeSocketEventRegistration(port, (int)socket.DangerousGetHandle(), currentEvents, newEvents, data);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #14
0
 internal static unsafe Error Accept(SafeHandle socket, byte* socketAddress, int* socketAddressLen, int* acceptedFd)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousAccept((int)socket.DangerousGetHandle(), socketAddress, socketAddressLen, acceptedFd);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
예제 #15
0
 internal static Error Listen(SafeHandle socket, int backlog)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousListen((int)socket.DangerousGetHandle(), backlog);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }