public void Copy(ref Msg src) { // Check the validity of the source. if (!src.Check()) { throw NetMQException.Create(ErrorCode.EFAULT); } Close(); if (m_type == MsgType.Pool) { // One reference is added to shared messages. Non-shared messages // are turned into shared messages and reference count is set to 2. if (src.m_flags.HasFlag(MsgFlags.Shared)) { src.m_atomicCounter.Increase(1); } else { src.m_flags |= MsgFlags.Shared; src.m_atomicCounter.Set(2); } } this = src; }
public void Move(ref Msg src) { // Check the validity of the source. if (!src.Check()) { throw NetMQException.Create(ErrorCode.EFAULT); } Close(); this = src; src.InitEmpty(); }
public void Recv(ref Msg msg, SendReceiveOptions flags) { CheckContextTerminated(); // Check whether message passed to the function is valid. if (!msg.Check()) { throw new FaultException(); } // Get the message. bool isMessageAvailable = XRecv(flags, ref 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) { ExtractFlags(ref msg); return; } // 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, ref msg); if (!isMessageAvailable) { throw new AgainException(); } ExtractFlags(ref msg); return; } // 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, ref msg); if (isMessageAvailable) { m_ticks = 0; break; } block = true; if (timeout > 0) { timeout = (int)(end - Clock.NowMs()); if (timeout <= 0) { throw new AgainException(); } } } ExtractFlags(ref msg); }
public void Send(ref Msg msg, SendReceiveOptions flags) { CheckContextTerminated(); // Check whether message passed to the function is valid. if (!msg.Check()) { throw new FaultException(); } // 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(ref 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 new AgainException(); } // 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(ref msg, flags); if (isMessageSent) { break; } if (timeout > 0) { timeout = (int)(end - Clock.NowMs()); if (timeout <= 0) { throw new AgainException(); } } } }