protected override void XSetSocketOption(ZmqSocketOptions option, Object optval) { if (option != ZmqSocketOptions.Subscribe && option != ZmqSocketOptions.Unsubscribe) { throw InvalidException.Create(); } byte[] val; if (optval is String) { val = Encoding.ASCII.GetBytes((String)optval); } else if (optval is byte[]) { val = (byte[])optval; } else { throw InvalidException.Create(); } // Create the subscription message. Msg msg = new Msg(); msg.InitPool(val.Length + 1); if (option == ZmqSocketOptions.Subscribe) { msg.Put((byte)1); } else if (option == ZmqSocketOptions.Unsubscribe) { msg.Put((byte)0); } msg.Put(val, 1, val.Length); try { // Pass it further on in the stack. bool isMessageSent = base.XSend(ref msg, 0); if (!isMessageSent) { throw AgainException.Create(); } } finally { msg.Close(); } }
public virtual void PushMsg(Msg msg) { // First message to receive is identity (if required). if (!m_identityReceived) { msg.SetFlags(MsgFlags.Identity); m_identityReceived = true; if (!m_options.RecvIdentity) { return; } } if (m_pipe != null && m_pipe.Write(msg)) { return; } throw AgainException.Create(); }
public Msg Recv(SendReceiveOptions flags) { if (m_ctxTerminated) { throw TerminatingException.Create(); } Msg msg; // Get the message. bool isMessageAvailable = XRecv(flags, out msg); // Once every inbound_poll_rate messages check for signals and process // incoming commands. This happens only if we are not polling altogether // because there are messages available all the time. If poll occurs, // ticks is set to zero and thus we avoid this code. // // Note that 'recv' uses different command throttling algorithm (the one // described above) from the one used by 'send'. This is because counting // ticks is more efficient than doing RDTSC all the time. if (++m_ticks == Config.InboundPollRate) { ProcessCommands(0, false); m_ticks = 0; } // If we have the message, return immediately. if (isMessageAvailable && msg != null) { ExtractFlags(msg); return(msg); } // If the message cannot be fetched immediately, there are two scenarios. // For non-blocking recv, commands are processed in case there's an // activate_reader command already waiting int a command pipe. // If it's not, return EAGAIN. if ((flags & SendReceiveOptions.DontWait) > 0 || m_options.ReceiveTimeout == 0) { ProcessCommands(0, false); m_ticks = 0; isMessageAvailable = XRecv(flags, out msg); if (!isMessageAvailable) { throw AgainException.Create(); } else if (msg == null) { return(null); } ExtractFlags(msg); return(msg); } // Compute the time when the timeout should occur. // If the timeout is infite, don't care. int timeout = m_options.ReceiveTimeout; long end = timeout < 0 ? 0 : (Clock.NowMs() + timeout); // In blocking scenario, commands are processed over and over again until // we are able to fetch a message. bool block = (m_ticks != 0); while (true) { ProcessCommands(block ? timeout : 0, false); isMessageAvailable = XRecv(flags, out msg); if (isMessageAvailable && msg != null) { m_ticks = 0; break; } block = true; if (timeout > 0) { timeout = (int)(end - Clock.NowMs()); if (timeout <= 0) { throw AgainException.Create(); } } } ExtractFlags(msg); return(msg); }
public void Send(Msg msg, SendReceiveOptions flags) { if (m_ctxTerminated) { throw TerminatingException.Create(); } // Check whether message passed to the function is valid. if (msg == null) { throw NetMQException.Create(ErrorCode.EFAULT); } // Process pending commands, if any. ProcessCommands(0, true); // Clear any user-visible flags that are set on the message. msg.ResetFlags(MsgFlags.More); // At this point we impose the flags on the message. if ((flags & SendReceiveOptions.SendMore) > 0) { msg.SetFlags(MsgFlags.More); } // Try to send the message. bool isMessageSent = XSend(msg, flags); if (isMessageSent) { return; } // In case of non-blocking send we'll simply propagate // the error - including EAGAIN - up the stack. if ((flags & SendReceiveOptions.DontWait) > 0 || m_options.SendTimeout == 0) { throw AgainException.Create(); } // Compute the time when the timeout should occur. // If the timeout is infite, don't care. int timeout = m_options.SendTimeout; long end = timeout < 0 ? 0 : (Clock.NowMs() + timeout); // Oops, we couldn't send the message. Wait for the next // command, process it and try to send the message again. // If timeout is reached in the meantime, return EAGAIN. while (true) { ProcessCommands(timeout, false); isMessageSent = XSend(msg, flags); if (isMessageSent) { break; } if (timeout > 0) { timeout = (int)(end - Clock.NowMs()); if (timeout <= 0) { throw AgainException.Create(); } } } }