Example #1
0
        protected virtual void Dispose(bool disposing)
        {
            const int ValidCloseResult = 0, MaxCloseAttemptCount = 5;

            // ensure that cleanup is only ever called once
            var socket = Interlocked.Exchange(ref _socket, NullSocket);

            if (socket != NullSocket)
            {
                int attemptCount = 0;
                while (true)
                {
                    if (Interop.nn_close(socket) != ValidCloseResult)
                    {
                        int error = Interop.nn_errno();

                        // if we were interrupted by a signal, reattempt is allowed by the native library
                        if (error == NanomsgSymbols.EINTR)
                        {
                            if (attemptCount++ >= MaxCloseAttemptCount)
                            {
                                if (disposing)
                                {
                                    throw new NanomsgException("nn_close " + socket.ToString(), error);
                                }
                                else
                                {
                                    // if we couldn't close the socket and we're on a finalizer thread, an exception would usually kill the process
                                    string errorText = string.Format("nn_close was repeatedly interrupted for socket {0}, which has not been successfully closed and may be leaked", socket);
                                    Trace.TraceError(errorText);
                                    Debug.Fail(errorText);
                                    return;
                                }
                            }
                            else
                            {
                                // reattempt the close
                                Thread.SpinWait(1);
                                continue;
                            }
                        }
                        else
                        {
                            Debug.Assert(error == NanomsgSymbols.EBADF);
                            // currently the only non-interrupt errors are for invalid sockets, which can't be closed
                            if (disposing)
                            {
                                throw new NanomsgException("nn_close " + socket.ToString(), error);
                            }
                            else
                            {
                                return;
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
Example #2
0
 public static int Close(int s)
 {
     return(Interop.nn_close(s));
 }