/// <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); } }
/// <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); } }
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); } }
/// <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); } }
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; } } } }
public static int Errno() { return(Interop.nn_errno()); }