Esempio n. 1
0
        /// <summary>
        /// Shuts down a specific endpoint of this socket.
        /// </summary>
        /// <param name="endpoint">The endpoint created by Connect or Bind which is being shut down.</param>
        /// <returns>True if the endpoint was shut down, false if the shutdown attempt was interrupted and should be reattempted.</returns>
        /// <exception cref="NNanomsg.NanomsgException">Thrown if the socket is in an invalid state or the endpoint's shutdown attempt was interrupted and should be reattempted.</exception>
        public bool Shutdown(NanomsgEndpoint endpoint)
        {
            const int ValidShutdownResult = 0, MaxShutdownAttemptCount = 5;
            int       attemptCount = 0;

            while (true)
            {
                if (Interop.nn_shutdown(_socket, endpoint.ID) != ValidShutdownResult)
                {
                    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++ >= MaxShutdownAttemptCount)
                        {
                            return(false);
                        }
                        else
                        {
                            Thread.SpinWait(1);
                            continue;
                        }
                    }

                    throw new NanomsgException("nn_shutdown " + endpoint.ID.ToString(), error);
                }
                return(true);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// If a message is pending, returns a stream containing its contents.  If no message is pending, returns null.
        /// </summary>
        /// <returns>A stream with message data, or null if no message has currently been received.</returns>
        /// <exception cref="NNanomsg.NanomsgException">Thrown if the socket is in an invalid state, the receive was interrupted, or the receive timeout has expired</exception>
        protected NanomsgReadStream ReceiveStreamImmediateImpl()
        {
            var stream = ReceiveStream(SendRecvFlags.DONTWAIT);

            if (stream == null)
            {
                int error = Interop.nn_errno();
                if (error == NanomsgSymbols.EAGAIN)
                {
                    return(null);
                }
                else
                {
                    throw new NanomsgException("nn_recv");
                }
            }
            else
            {
                return(stream);
            }
        }
Esempio n. 3
0
        protected bool SendStreamImmediateImpl(NanomsgWriteStream stream)
        {
            int sentBytes = SendStreamImpl(stream, SendRecvFlags.DONTWAIT);

            if (sentBytes < 0)
            {
                int error = Interop.nn_errno();
                if (error == NanomsgSymbols.EAGAIN)
                {
                    return(false);
                }
                else
                {
                    throw new NanomsgException("nn_send", error);
                }
            }
            else
            {
                Debug.Assert(sentBytes == stream.Length);
                return(true);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Sends the data.  If a send buffer cannot be immediately acquired, this method returns false and no send is performed.
        /// </summary>
        /// <param name="buffer">The data to send.</param>
        /// <returns>True if the data was sent, false if the data couldn't be sent at this time, and should be reattempted.</returns>
        /// <exception cref="NNanomsg.NanomsgException">Thrown if the socket is in an invalid state, the send was interrupted, or the send timeout has expired</exception>
        protected bool SendImmediateImpl(byte[] buffer)
        {
            int sentBytes = Interop.nn_send(_socket, buffer, buffer.Length, (int)SendRecvFlags.DONTWAIT);

            if (sentBytes < 0)
            {
                int error = Interop.nn_errno();
                if (error == NanomsgSymbols.EAGAIN)
                {
                    return(false);
                }
                else
                {
                    throw new NanomsgException("nn_send", error);
                }
            }
            else
            {
                Debug.Assert(sentBytes == buffer.Length);
                return(true);
            }
        }
Esempio n. 5
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;
                    }
                }
            }
        }
Esempio n. 6
0
 public static int Errno()
 {
     return(Interop.nn_errno());
 }