protected override bool ReleaseHandle()
        {
            int error = 0;

            Socket.Blocking_icall(handle, false, out error);
#if FULL_AOT_DESKTOP
            /* It's only for platforms that do not have working syscall abort mechanism, like WatchOS and TvOS */
            Socket.Shutdown_icall(handle, SocketShutdown.Both, out error);
#endif

            if (blocking_threads != null)
            {
                lock (blocking_threads) {
                    int abort_attempts = 0;
                    while (blocking_threads.Count > 0)
                    {
                        if (abort_attempts++ >= ABORT_RETRIES)
                        {
                            if (THROW_ON_ABORT_RETRIES)
                            {
                                StringBuilder sb = new StringBuilder();
                                sb.AppendLine("Could not abort registered blocking threads before closing socket.");
                                foreach (var thread in blocking_threads)
                                {
                                    sb.AppendLine("Thread StackTrace:");
                                    sb.AppendLine(threads_stacktraces[thread].ToString());
                                }
                                sb.AppendLine();

                                throw new Exception(sb.ToString());
                            }

                            // Attempts to close the socket safely failed.
                            // We give up, and close the socket with pending blocking system calls.
                            // This should not occur, nonetheless if it does this avoids an endless loop.
                            break;
                        }

                        /*
                         * This method can be called by the DangerousRelease inside RegisterForBlockingSyscall
                         * When this happens blocking_threads contains the current thread.
                         * We can safely close the socket and throw SocketException in RegisterForBlockingSyscall
                         * before the blocking system call.
                         */
                        if (blocking_threads.Count == 1 && blocking_threads[0] == Thread.CurrentThread)
                        {
                            break;
                        }

                        // abort registered threads
                        foreach (var t in blocking_threads)
                        {
                            Socket.cancel_blocking_socket_operation(t);
                        }

                        // Sleep so other threads can resume
                        in_cleanup = true;
                        Monitor.Wait(blocking_threads, 100);
                    }
                }
            }

            Socket.Close_icall(handle, out error);

            return(error == 0);
        }